Несколько объявлений функций C ++ с параметрами по умолчанию - PullRequest
5 голосов
/ 15 июля 2011

Я использую typedefs почти для всего, включая функции.В течение последних нескольких недель я настраивал наш код C ++, чтобы он как можно точнее соответствовал стандарту ISO C ++ 11, используя в качестве руководства окончательный проект документа (N3242).

Как мы знаемИногда в нашем коде появляются несколько объявлений, которые появляются в более чем одном файле во внешних файлах, или повторяющиеся определения типа.Согласно этому отрывку из раздела 7.1.3, стр. 145 вышеупомянутого документа, это должно быть безвредно:

3.В данной области, не относящейся к классу, спецификатор typedef может использоваться для переопределения имени любого типа, объявленного в этой области, для ссылки на тип, к которому он уже относится.

[Пример:

   typedef struct s { /* ... */ } s; 
   typedef int I; 
   typedef int I; 
   typedef I I;

- конец примера]

Итак, я написал программу для проверки этого.В простейшем виде:

typedef int (fcntype)(int, int);
extern fcntype fcn1;

int fcn1(int x, int y) { return x + y; }

int main(int argc, char ** argv) { return fcn1(2, 3); }

Компиляция с использованием gcc с

 -Wfatal-errors -Wswitch-default -Wswitch-enum -Wunused-parameter -Wfloat-equal -Wundef -c -Wstrict-null-sentinel -std=c++0x -pedantic -Wall -Wextra

, конечно, проблем не возникает.Давайте дублируем функцию decl:

typedef int (fcntype)(int, int);
extern fcntype fcn1;
extern fcntype fcn1; // woops. probably from an #include ...

int fcn1(int x, int y) { return x + y; }

int main(int argc, char ** argv) { return fcn1(2, 3); }

Как и предсказывает стандарт, проблем нет.Давайте сделаем другое изменение оригинала:

typedef int (fcntype)(int, int=0); // default param.
extern fcntype fcn1;

int fcn1(int x, int y) { return x + y; }

int main(int argc, char ** argv) { return fcn1(2); } // use the default param

Опять без проблем.Проблема возникает, когда у нас есть как дубликат decl, так и параметр по умолчанию, например:

typedef int (fcntype)(int, int=0); // default param.
extern fcntype fcn1;
extern fcntype fcn1; // FYI this is line 3 in the error message below.

int fcn1(int x, int y) { return x + y; }

int main(int argc, char ** argv) { return fcn1(2); } // use the default param

И gcc жалуется на

decltest.cpp:3: error: default argument given for parameter 2 of ‘int fcn1(int, int)’

Конечно, я очищаю кодкак это должно быть очищено, то есть я собираю файлы в один, лучше организованный файл.Но является ли это ошибкой в ​​компиляторе или моим неправильным пониманием того, что параметр по умолчанию "is"?

Ответы [ 3 ]

6 голосов
/ 15 июля 2011

Во-первых, для одного и того же объявления функции с одинаковыми типами должно быть не более одного объявления, определяющего аргументы по умолчанию. Это связано с §8.3.6 [dcl.fct.default] / 4:

... Аргумент по умолчанию не должен быть переопределен более поздним объявлением (даже с тем же значением). [ Пример :

...
void m() {
    void f(int, int);     // has no defaults
    f(4);                 // error: wrong number of arguments
    void f(int, int = 5); // OK
    f(4);                 // OK, calls f(4, 5);
    void f(int, int = 5); // error: cannot redefine, even to same value
}
...

- конец примера ] ...

Также, как заметил @Sven, аргумент по умолчанию не должен появляться в typedef, хотя g ++ не может его перехватить даже с -pedantic. Я думаю clang и Visual C ++ отвергают это, но я не пробовал.

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

Ваша стандартная цитата здесь не применяется, поскольку вы не объявляете typedef несколько раз, а используете его несколько раз.

Аргументы по умолчанию действительно сложны, они могут появляться только в одном объявлении(и помните, само определение считается объявлением, даже если в предварительном объявлении и определении задан аргумент по умолчанию, это ошибка).

0 голосов
/ 17 июля 2011

Выдает ту же ошибку:

extern int fcn1(int, int=0);
extern int fcn1(int, int=0);

Так что неудивительно, что ваша typedef версия не работает.

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