Поддерживает ли C++ массивы переменной длины?

Нет, подожди, потерпи меня...

VLA всегда были расширением GCC, но они были приняты C99:

[C99: 6.7.5.2/4]: Если размер отсутствует, тип массива является неполным. Если размер * вместо выражения, тип массива является типом массива переменной длины неопределенного размера, который может использоваться только в объявлениях с областью действия прототипа функции; такие массивы, тем не менее, являются полными типами. Если размер представляет собой целочисленное константное выражение, а тип элемента имеет известный постоянный размер, тип массива не является типом массива переменной длины; в противном случае тип массива является типом массива переменной длины.

C99 также известен как ISO/IEC 9899:1999.

Сейчас:

[C++11: 1.1/2]: C++ — это язык программирования общего назначения, основанный на языке программирования C, как указано в ISO/IEC 9899:1999 (далее — стандарт C). В дополнение к возможностям, предоставляемым C, C++ предоставляет дополнительные типы данных, классы, шаблоны, исключения, пространства имен, перегрузку операторов, перегрузку имен функций, ссылки, свободные операторы управления хранилищем и дополнительные библиотечные возможности.

Разве в C++11 тоже не должны быть VLA?


person Lightness Races in Orbit    schedule 21.12.2011    source источник
comment
Связано: stackoverflow.com/ questions/1887097/variable-length-arrays-in-c (хотя мой вопрос на самом деле касается того, где технически заявлено, что эта функция не унаследована от C99 в первую очередь; другой касается вопроса о том, может ли комитет явно сделай так)   -  person Lightness Races in Orbit    schedule 21.12.2011
comment
Во всяком случае, на основе языка программирования Си информативный текст, я думаю. В дополнение к средствам, предоставляемым C, означает в дополнение к некоторым средствам, предоставляемым C и которые мы включили в C++, не о, и если есть что-то из C, что мы забыли упомянуть в следующем тексте, то это тоже в C++ ;- )   -  person Steve Jessop    schedule 21.12.2011
comment
@ Стив: хорошо. Возможно, проблема, с которой я тогда столкнулся, заключается в том, что я предположил, что язык C, а также стандартная библиотека C по умолчанию унаследованы от C99. Возможно, это просто библиотека, а язык просто указан как основа для дизайна.   -  person Lightness Races in Orbit    schedule 21.12.2011
comment
Что ж, каждая библиотечная функция, в свою очередь, взятая из C, указана в стандарте C++ со ссылкой на стандарт C99, в которой говорится, что эта функция такая же, как и там, и в некоторых случаях... со следующим отличием. Так что я согласен, что нет массового наследования, просто упражнение по сбору вишен, которое собирает 99% вишен.   -  person Steve Jessop    schedule 21.12.2011
comment
@Steve: Хех, ладно. Тогда это имеет смысл.   -  person Lightness Races in Orbit    schedule 21.12.2011
comment
VLA C99 ведут себя иначе, чем массивы GCC. C99 не принял массивы GCC.   -  person M.M    schedule 28.08.2014


Ответы (4)


Эта свободная формулировка не означает, что все в C99 есть в C++11. То, что вы цитируете, является лишь вступительным текстом.

person Johannes Schaub - litb    schedule 21.12.2011
comment
Возвращаясь к этому, то, что я цитировал, является нормативным и, кажется, в значительной степени подразумевает, что C++ предоставляет the facilities provided by C - person Lightness Races in Orbit; 08.01.2013
comment
@LightnessRacesinOrbit, из чего конкретно в этом предложении вы это делаете? Утверждение А основано на Б не означает, что каждая черта В присутствует в А. Например, фильм, основанный на реальных событиях, не содержит всех черт реальной истории, на которой он основан. И если вы пишете предложение, основанное на другом предложении, это не обязательно означает, что какие-либо особенности, имеющиеся в другом предложении, также присутствуют в вашем предложении. Если не дать формального определения основанного на отношении отношения, я буду использовать стандартное повседневное значение. - person Johannes Schaub - litb; 27.06.2016
comment
Это не основано на предложении. Это предложение после него. В дополнение к возможностям, предоставляемым C, C++ предоставляет... Это означает, что C++ предоставляет как минимум возможности, предоставляемые C. - person Lightness Races in Orbit; 27.06.2016
comment
Я читал, что удобство может означать что-то, что облегчает выполнение действия. Я предполагаю, что парень, написавший это предложение, считает, что VLA не упрощают создание массива переменной длины. - person Johannes Schaub - litb; 27.06.2016
comment
Наличие поддержки VLA в языке упрощает создание массива переменной длины. - person Lightness Races in Orbit; 27.06.2016
comment
@light Я спорил для развлечения :) да, я согласен, это означало бы, что C ++ имеет VLA. Но я не считаю это недостатком (во всяком случае, это противоречие с более поздним текстом, который делает VLA неправильными, а не разрешает VLA). Вводные абзацы намеренно неточны (IIRC также упоминался на странице о том, как сообщить о проблеме группы usenet std-С++, в качестве предостережения). - person Johannes Schaub - litb; 28.06.2016
comment
(во всяком случае, это противоречит более позднему тексту, который делает VLA неправильными, а не разрешает VLA) Именно в этом вопрос :) - person Lightness Races in Orbit; 28.06.2016

Эта функция C99 эффективно перекрывается собственной семантикой C++, как и любая другая "унаследованная" функция:

[C++11: 8.3.4/1]: В объявлении T D, где D имеет вид

D1 [ константное-выражениеopt ] определитель-атрибута-seqopt

[..]

Это единственный синтаксис объявления массива, который нам дан в C++.

Обратите внимание, что это различие не упоминается в пункте C.1 "совместимость с C".

person Lightness Races in Orbit    schedule 21.12.2011
comment
Я не думаю, что это даже переопределение - функции C не находятся в C ++ по наследству, они там благодаря композиции и экспозиции. Любая функция C, не упомянутая явно в стандарте C++, отсутствует, точно так же, как если бы C++ ничего не унаследовал от C, а просто по совпадению содержит похожий текст. Но авторы явно мотивированы предоставлять функции C там, где это возможно и где они не считают себя глупыми. - person Steve Jessop; 21.12.2011
comment
int x = foo(); int n[x]; считается? У меня это работает на g++ 4.6. Конечно, x здесь не является постоянным выражением? - person Aaron McDaid; 21.12.2011
comment
@Aaron McDaid Если вы не компилировали с -pedantic (или это -ansi?), вы, вероятно, получили расширение g++. - person Mark B; 21.12.2011
comment
@MarkB, -pedantic дает мне template.cpp:7:12: предупреждение: ISO C++ запрещает массив переменной длины ‘n’ [-Wvla] Раньше у меня были -Wall и -Wextra. - person Aaron McDaid; 21.12.2011
comment
Спасибо @MarkB, я соответствующим образом изменю свой ответ. - person Aaron McDaid; 21.12.2011
comment
@AaronMcDaid: Ну вот. :) VLA должны быть отключены по умолчанию IMO ›.‹ - person Lightness Races in Orbit; 21.12.2011
comment
Да :-) В C++ есть очевидные альтернативы VLA. Кроме того, мне нужна опция, которая действительно включает все предупреждения. Достаточно ли -Wall -Wextra -pedantic? По крайней мере, пока я не решу, какие предупреждения снова отключить. - person Aaron McDaid; 21.12.2011
comment
Чтобы действительно получить много предупреждений, вы должны использовать -Wall -Wextra -std=c++98 -pedantic или -Wall -Wextra -std=c++0x -pedantic (так что да). - person Lightness Races in Orbit; 21.12.2011
comment
С точки зрения GCC, вопрос не во всех предупреждениях, а в том, какой язык вы хотите, чтобы я скомпилировал. Если вы не говорите -pedantic, то вы компилируете не C++, а компилируете C++-с-расширениями. Если вы скажете std=gnu++0x, вы получите расширения и также языковые изменения, которые противоречат стандарту, а не расширяют его. Я предполагаю, что составители компиляторов не делают это значение по умолчанию по той же причине, по которой они считают хорошей идеей расширить язык в первую очередь (сочетание высокомерия и нытья клиентов). - person Steve Jessop; 21.12.2011
comment
@SteveJessop: Больше побед от тебя. - person Lightness Races in Orbit; 21.12.2011
comment
Также обратите внимание, что gnu++98 используется по умолчанию, поэтому, если вы вообще ничего не говорите, у вас нет соответствующего компилятора C++. - person Steve Jessop; 21.12.2011
comment
что действительно означает расширение? - person Johannes Schaub - litb; 24.12.2011
comment
@Johannes - Это означает, что любая допустимая программа на C ++ компилируется ... И некоторые недопустимые программы тоже компилируются. - person Nemo; 15.08.2012

Определение константного выражения отличается для двух языков.

const size_t size = 5;
int array[size]; // array in C++, VLA in C
person Happy Green Kid Naps    schedule 21.12.2011
comment
@DrumM -- О чем ты говоришь? Думали ли вы о другом ответе (или вопросе?!), когда добавляли свой комментарий? Что не так с ответом, который заставил бы вас проголосовать против? - person Happy Green Kid Naps; 08.07.2020
comment
Ваш ответ отражает constexpr, что невозможно в 99% случаев, люди используют массив переменной длины, когда размер не равен const, например. когда это входная переменная. Таким образом, даже если вы объявляете константу из входной переменной, это все равно не константа времени компиляции. const size_t size = 5; - это просто бесполезная дополнительная строка... - person DrumM; 10.07.2020
comment
Во-первых, что вы имели в виду под Это не устраняет предупреждение? Во-вторых, я объяснял тонкую разницу между C и C++ для синтаксически идентичных строк в двух языках. Вводя constexpr и рассматривая объявление const int как бесполезную дополнительную строку , вы явно упускаете суть. - person Happy Green Kid Naps; 10.07.2020

Это компилируется для меня: (g++ 4.6 с -std=c++0x). Но он не компилируется с -pedantic (спасибо @MarkB). Вместо этого он предупреждает, что «template.cpp:7:12: предупреждение: ISO C++ запрещает массив переменной длины ‘n’ [-Wvla]»

int main(int argc, char ** argv) {
    int n[argc];
}

Таким образом, размер n не может быть известен компилятору во время компиляции. Является ли это расширением GNU для C++? Похоже, что это расширение GNU, и что VLA не являются официальной частью C++11.

(Конечно, я просто играю с компилятором. Так что отнеситесь к этому с щепоткой соли.)

person Aaron McDaid    schedule 21.12.2011
comment
(a) GCC также имеет VLA в качестве расширения. (b) В прошлом я видел сбои в определении того, когда размерность массива является переменной. - person Lightness Races in Orbit; 21.12.2011
comment
Это расширение g++. Если вы компилируете с помощью -pedantic, он предупреждает, что он использует расширение компилятора и не ISO C++. - person Mark B; 21.12.2011