Возможно, я не с этой планеты, но мне кажется, что синтаксическая ошибка должна быть следующей:
int a[] = {1,2,}; //extra comma in the end
Но это не так. Я был удивлен , когда этот код скомпилирован на Visual Studio, но я научился не доверять MSVC компилятор, насколько правила C ++ обеспокоены, так что я проверил стандарт и это допускается стандартом , а также. Вы можете увидеть 8.5.1 правила грамматики, если не верите мне.
Почему это разрешено? Это может быть глупый бесполезный вопрос, но я хочу, чтобы вы поняли, почему я спрашиваю. Если бы это был подслучайный случай общего правила грамматики, я бы понял - они решили не усложнять общую грамматику, просто запретив избыточную запятую в конце списка инициализатора. Но нет, дополнительная запятая явно разрешена. Например, не допускается иметь избыточную запятую в конце списка аргументов вызова функции (когда функция принимает ...
), что является нормальным .
Итак, опять же, есть ли какая-то особая причина, по которой эта избыточная запятая явно разрешена?
источник
;
когда ясно, что следующий токен - это на самом деле следующее утверждение.for()
), добавление его вызывает предупреждение компилятора.if (x = 1)
же не является двусмысленным в грамматике, но это очень двусмысленно для людей, и поэтому выдает предупреждение.if
пример тоже не является двусмысленным. Я не думаю, что «неоднозначно» означает то, что вы думаете, что это значит!Ответы:
Это облегчает генерацию исходного кода, а также написание кода, который может быть легко расширен позднее. Подумайте, что требуется для добавления дополнительной записи в:
... вы должны добавить запятую к существующей строке и добавить новую строку. Сравните это со случаем, когда тройка уже имеет запятую после нее, где вам просто нужно добавить строку. Аналогично, если вы хотите удалить строку, вы можете сделать это, не беспокоясь о том, является ли она последней или нет, и вы можете изменить порядок строк, не запутываясь в запятых. По сути, это означает, что в отношении к линиям есть единообразие.
Теперь подумайте о генерации кода. Что-то вроде (псевдокод):
Не нужно беспокоиться о том, является ли текущий элемент, который вы записываете, первым или последним. Гораздо проще
источник
Это полезно, если вы делаете что-то вроде этого:
источник
var a = [1, 2,];
и большинство других известных мне языков ... ActionScript, Python, PHP.undefined
.Простота использования для разработчика, я думаю.
Кроме того, если по какой-либо причине у вас был инструмент, который генерировал код для вас; инструмент не должен заботиться о том, является ли он последним элементом в инициализации или нет.
источник
Я всегда предполагал, что это облегчает добавление дополнительных элементов:
просто становится:
впоследствии.
источник
[1,2,3,]
в порядке, но{a:1, b:2, c:3,}
нет).Все, что все говорят о легкости добавления / удаления / генерации строк, является правильным, но реальный смысл этого синтаксиса - объединение исходных файлов. Представьте, что у вас есть этот массив:
И предположим, что вы проверили этот код в хранилище.
Затем ваш друг редактирует его, добавляя в конец:
И вы одновременно редактируете это, добавляя в начало:
Семантически эти виды операций (добавление в начало, добавление в конец) должны быть полностью безопасны для слияния, а программное обеспечение управления версиями (возможно, git) должно иметь возможность автоматического объединения. К сожалению, это не так, потому что у вашей версии нет запятой после 9, а у вашего собеседника - нет. Принимая во внимание, что, если бы у оригинальной версии был завершающий 9, они бы объединились.
Итак, мое правило: используйте запятую, если список занимает несколько строк, не используйте ее, если список находится на одной строке.
источник
Конечная запятая, я считаю, разрешена по причинам обратной совместимости. Существует много существующего кода, в основном сгенерированного автоматически, который ставит запятую. Это облегчает написание цикла без особых условий в конце. например
Для программиста нет никаких преимуществ.
PS Хотя таким способом проще генерировать код, на самом деле я всегда старался не ставить конечную запятую, усилия минимальны, читаемость улучшена, и это важнее. Вы пишете код один раз, вы читаете его много раз.
источник
int a = b + c +;
иначеif(a && b &&);
будет проще просто скопировать и вставить что-нибудь в конце и проще написать генераторы кода. Эта проблема является как тривиальной, так и субъективной, в таких случаях всегда полезно делать то, что лучше для читателя кода.&&
оператора, иногда я делаю условные выражения, например,if (true \n && b1 \n && b2)
чтобы добавлять и удалять строки по мере необходимости.Насколько мне известно, одна из причин, по которой это разрешено, заключается в простоте автоматической генерации кода; вам не нужно никакой специальной обработки для последнего элемента.
источник
Это облегчает генераторы кода, которые выкладывают массивы или перечисления.
Представить:
Т.е. не нужно делать специальную обработку первого или последнего элемента, чтобы не выплевывать запятую.
Например, если генератор кода написан на Python, легко избежать разбрызгивания запятой, используя
str.join()
функцию:источник
Я удивлен, что за все это время никто не процитировал Аннотированное справочное руководство C ++ ( ARM ), в нем говорится следующее о [dcl.init] с акцентом на мое:
хотя грамматика эволюционировала с момента написания ARM, происхождение остается.
и мы можем перейти к обоснованию C99, чтобы понять, почему это было разрешено в C, и там написано:
источник
Я вижу один вариант использования, который не был упомянут в других ответах, наши любимые макросы:
Добавление макросов для обработки последних
,
будет большой болью. С этим небольшим изменением синтаксиса этим тривиально управлять. И это более важно, чем машинно-сгенерированный код, потому что, как правило, гораздо проще сделать это в полном языке Тьюринга, чем очень ограниченный препроцессор.источник
Единственный язык, на котором это - на практике * - не допускается, - это Javascript, и это вызывает неисчислимое количество проблем. Например, если вы скопируете и вставите строку из середины массива, вставите ее в конце и забудете удалить запятую, тогда ваш сайт будет полностью поврежден для ваших посетителей IE.
* Теоретически это разрешено, но Internet Explorer не следует стандарту и рассматривает его как ошибку
источник
var x = [,,,]
допустимы (кроме IE <9, но спецификация говорит, что это разрешено)Это проще для машин, то есть для анализа и генерации кода. Это также легче для людей, то есть модификация, комментирование и визуальная элегантность через последовательность.
Предполагая C, вы бы написали следующее?
Нет. Не только потому, что последнее утверждение является ошибкой, но и потому, что оно несовместимо. Так почему же то же самое с коллекциями? Даже в тех языках, которые позволяют пропустить последние точки с запятой и запятые, сообществу это обычно не нравится. Сообщество Perl, например, не любит опускать точки с запятой, кроме однострочных. Они также применяют это к запятым.
Не пропускайте запятые в многострочных коллекциях по той же причине, по которой вы не пропускаете точки с запятой для многострочных блоков кода. Я имею в виду, вы бы не сделали этого, даже если бы язык позволял это, верно? Правильно?
источник
Причина тривиальна: простота добавления / удаления строк.
Представьте себе следующий код:
Теперь вы можете легко добавлять / удалять элементы в списке без необходимости иногда добавлять / удалять завершающую запятую.
В отличие от других ответов, я на самом деле не думаю, что легкость генерирования списка является веской причиной: в конце концов, тривиально, чтобы код специально выделил последнюю (или первую) строку. Генераторы кода пишутся один раз и используются много раз.
источник
Это позволяет каждой строке следовать той же форме. Во-первых, это облегчает добавление новых строк и позволяет системе контроля версий осмысленно отслеживать изменения, а также позволяет легче анализировать код. Я не могу думать о технической причине.
источник
Это позволяет защитить от ошибок, вызванных перемещением элементов в длинном списке.
Например, предположим, что у нас есть код, похожий на этот.
И это здорово, так как показывает оригинальную трилогию сайтов Stack Exchange.
Но есть одна проблема с этим. Видите ли, нижний колонтитул на этом сайте показывает сбой сервера перед суперпользователем. Лучше исправить это, прежде чем кто-нибудь заметит.
В конце концов, перемещение линий не может быть таким сложным, не так ли?
Я знаю, что нет сайта под названием «Server FaultSuper User», но наш компилятор утверждает, что он существует. Теперь проблема в том, что в C есть функция конкатенации строк, которая позволяет вам писать две строки в двойных кавычках и объединять их, не используя ничего (аналогичная проблема может возникнуть и с целыми числами, так как
-
знак имеет несколько значений).А что если исходный массив имеет бесполезную запятую в конце? Ну, линии будут перемещаться, но такой ошибки не было бы. Легко пропустить что-то такое маленькое, как запятая. Если вы не забыли ставить запятую после каждого элемента массива, такой ошибки просто не может быть. Вы бы не хотели тратить четыре часа на отладку чего-либо, пока не обнаружите, что причиной ваших проблем является запятая .
источник
Как и многие другие, конечная запятая в инициализаторе массива - это одна из вещей, наследуемых C ++ от C (и ее придется поддерживать всегда). Представление, совершенно отличное от представленного здесь , упоминается в книге «Секреты глубокой С» .
Вот пример с более чем одним «парадоксом запятой»:
мы читаем :
... для меня это имеет больше смысла
источник
enum
случае несколько интересен, поскольку именно в этом случае пропущенная запятая будет представлять наименьшую двусмысленность. Даноstruct foo arr[] = {{1,2,3,4,5}, {3,4,5,6,7}, }
; Есть два разумных значения, которые язык может назначить: создать массив из двух элементов или создать массив из трех элементов, где последний элемент имеет значения по умолчанию. Если бы C принял более позднюю интерпретацию, я мог бы видеть запрещающиеenum foo {moe, larry, curly, };
по принципу, что должен быть только один способ написать утверждение (без запятой), но ...enum foo {moe,,larry,curly,};
как пропуск числа междуmoe
иlarry
, как правило, не имеет значения, обрабатывается ли запятая запятая или игнорируется. Единственный случай, когда это могло бы иметь значение, было бы, если бы последним элементом было максимальное значение для его объявленного типа, и это ...В дополнение к простоте генерации и редактирования кода, если вы хотите реализовать синтаксический анализатор, этот тип грамматики проще и проще в реализации. C # следует этому правилу в нескольких местах, где есть список разделенных запятыми элементов, таких как элементы в
enum
определении.источник
Это облегчает генерацию кода, так как вам нужно добавить только одну строку и не нужно обрабатывать добавление последней записи, как будто это особый случай. Это особенно верно при использовании макросов для генерации кода. Есть попытка устранить необходимость в макросах из языка, но многие языки развивались рука об руку с доступными макросами. Дополнительная запятая позволяет определять и использовать такие макросы, как следующие:
Использование:
Это очень упрощенный пример, но часто этот шаблон используется макросами для определения таких вещей, как карты и таблицы отправки, сообщения, события или перевода. Если запятая не была разрешена в конце, нам нужно специальное:
и это было бы очень неудобно в использовании.
источник
Таким образом, когда два человека добавляют новый элемент в список в отдельных ветвях, Git может правильно объединить изменения, потому что Git работает на линейной основе.
источник
Если вы используете массив без заданной длины, VC ++ 6.0 может автоматически определить его длину, поэтому если вы используете "int a [] = {1,2,};" длина a равна 3, но последний не имеет ' t был инициализирован, вы можете использовать "cout <
источник