запятая в списке параметров подразумевает пустые символы? - PullRequest
0 голосов
/ 06 июля 2011

В VS2010 следующий код компилируется и запускается в файле .c:

void F1(,a,b,c,d,e){}  // Note the leading comma.

void F2(void){
 int x = 10;
 void* y = 0;
 F1(x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, y);  // Compiles fine.
}

То есть он действует так, как будто его где-то видели:

void F1();

Следующий код не компилируется с неизвестной ошибкой идентификатора в строке printf для каждого параметра:

void F1(,a,b,c,d,e){
 printf("%d, %d, %d, %d, %d\n", a, b, c, d, e);
}

Является ли это частью стандарта C? Есть идеи, что происходит?

Ответы [ 2 ]

3 голосов
/ 06 июля 2011

Это недопустимо C99: список параметров должен указывать типы параметров;в C90 они по умолчанию int.

И, я думаю, это также незаконно в C99, потому что текст в Стандарт (6.9.1) использует форму «должен» для параметрасписок типов и список идентификаторов. Я предполагаю, что то же самое верно для C90, делающего код недопустимым и с этим языком, по той же причине, но сейчас я не могу это проверить.

6.9.1 / 5 Если декларатор включает список типов параметров, объявление каждого параметра должно включать идентификатор, за исключением особого случая списка параметров, состоящего из одного параметра типа void,в этом случае не должно быть идентификатора.Список объявлений не должен следовать.

6.9.1 / 6 Если декларатор включает в себя список идентификаторов, каждое объявление в списке объявлений должно иметь по крайней мере один декларатор,эти деклараторы должны объявлять только идентификаторы из списка идентификаторов, и каждый идентификатор в списке идентификаторов должен быть объявлен.Идентификатор, объявленный как имя определения типа, не должен быть повторно объявлен как параметр.Объявления в списке объявлений не должны содержать спецификатора класса хранения, кроме регистра, и никаких инициализаций.

1 голос
/ 06 июля 2011

Нет, это не стандартное поведение. Сообщить об ошибке . Стандарт C89 (черновая версия доступна здесь ) определяет синтаксис определения функции (§3.7.1):

3.7.1 Function definitions

Syntax

          function-definition:
                  declaration-specifiers<opt> declarator
                            declaration-list<opt> compound-statement

И §3.5.4 определяет декларатор :

3.5.4 Declarators

Syntax

          declarator:
                  pointer<opt> direct-declarator

          direct-declarator:
                  identifier
                  (  declarator ) 
                  direct-declarator [  constant-expression<opt> ] 

                  direct-declarator (  parameter-type-list ) 
                  direct-declarator (  identifier-list<opt> )

          pointer:
                  *  type-qualifier-list<opt>
                  *  type-qualifier-list<opt> pointer

          type-qualifier-list:
                  type-qualifier
                  type-qualifier-list type-qualifier

          parameter-type-list:
                  parameter-list
                  parameter-list , ...

          parameter-list:
                  parameter-declaration
                  parameter-list ,  parameter-declaration

          parameter-declaration:
                  declaration-specifiers declarator
                  declaration-specifiers abstract-declarator<opt>

          identifier-list:
                  identifier
                  identifier-list ,  identifier

В случае определения void F1(,a,b,c,d,e){}, void является спецификатором объявления , а F1(,a,b,c,d,e) является (предположительно) декларатором . Из 5 возможных альтернатив для прямого объявления единственные, с которыми он может соответствовать, - это последние два. Но подвыражение в скобках ,a,b,c,d,e) не соответствует ни списка типов параметров , ни списка идентификаторов , так что это некорректное выражение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...