2015-10-25 4 views
3

Рассмотрим следующую программу:Действительно ли это неопределенное поведение для вызова макроса с пустыми аргументами на C89 и C++?

#include <iostream> 
#define add(s,m,a) (s + m + a + 0) 
int main() 
{ 
    std::cout<<add(3,4,5)<<'\n'; 
    std::cout<<add(15,30,)<<'\n'; 
    std::cout<<add(10, , 33)<<'\n'; 
    std::cout<<add(10,,)<<'\n'; 
    std::cout<<add(,,)<<'\n'; 
} 

Мой компилятор GCC 4.8.1 дает следующие предупреждения:

6 23 [Warning] invoking macro add argument 3: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default] 

7 25 [Warning] invoking macro add argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default] 

8 21 [Warning] invoking macro add argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default] 

8 21 [Warning] invoking macro add argument 3: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default] 

9 19 [Warning] invoking macro add argument 1: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default] 

9 19 [Warning] invoking macro add argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default] 

9 19 [Warning] invoking macro add argument 3: empty macro arguments are undefined in ISO C90 and ISO C++98 [enabled by default] 

Я знаю, что C++ не поддерживает пустые функции препроцессора макросы аргументы. Но C99 позволяет указать макросы препроцессорной функции с пустыми (отсутствующими) аргументами.

(Эта функция, вероятно, будет предоставлена ​​как расширение многими компиляторами C++, такими как g ++ в приведенном выше случае). Является ли поведение программы действительно неопределенным в соответствии со стандартом C89 & C++?

+0

Посмотрите его в фактическом стандарте (или черновике). –

ответ

8

Стандарты C89/C90 и C++ 98 просто не определили, как обрабатывать пустые аргументы макроса. В результате поведение было неопределенным бездействием, и сообщение об ошибке предварительной обработки или ошибки является разумным результатом этого.

C99, как вы отметили, был первым стандартом C, позволяющим это сделать, но стоит упомянуть также, что C++ 11 принял формулировку C99. Нет, это уже не неопределенное поведение на C++, чтобы иметь пустые аргументы макроса.

+0

Документ, внешне похожий на стандарт ISO C90, можно найти здесь (http://port70.net/~nsz/c/c89/c89-draft.html). Я не могу ручаться за его действительность. Посмотрите 3.8.3, последний абзац перед 3.8.3.1. –