2015-10-23 2 views
0

Я хочу узнать, как использовать макрос.VARIADIC MACRO ошибка компиляции

Я просто написать образец, но не компилируется на моей локальной г ++ 4,9

#define P(...) printf("13", ##__VA_ARGS__) 
int main() { 
// your code goes here 
P(); 
return 0; 
} 

я получить компилировать ошибку, как показано ниже

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out 
main.cpp: In function 'int main()': 
main.cpp:4:42: error: expected primary-expression before ')' token 
#define P(...) printf("13", ##__VA_ARGS__) 
             ^
main.cpp:7:5: note: in expansion of macro 'P' 
    P(); 
    ^

Но тот же код может быть составлен на ideone .... http://ideone.com/ucEXXz

а также VS2015.

Есть ли разумные объяснения для этого?

Как я могу написать переносимый макрос для все компилятора ....

Спасибо.

+0

код не совпадает - на coliru stdio.h не входит - iostream является ... – onqtam

+0

Удалить '-std = C++ 14' – qrdl

ответ

0

В C функции, которые принимают переменные, требуют объявления прототипа, а на C++ все функции требуют прототипа. Объявление для printf можно найти в stdio.h.

#include <stdio.h> 
#define P(...) printf("13", ##__VA_ARGS__) 
int main() { 
P(); 
return 0; 
} 

Синтаксис ##__VA_ARGS__ нестандартно. Это «запятая запятая, если __VA_ARGS__ пуст» расширение, реализованное GCC, и, похоже, было принято другими компиляторами.

Что касается поведения -std=c++14:

Компилятор может принимать несколько стандартов основания, такого как «C90» или «C++ 98» и GNU диалекты этих стандартов, таких как «» или gnu90 'GNU ++ 98'. Когда задан базовый стандарт, компилятор принимает все программы, следующие за этим стандартом, плюс те, которые используют расширения GNU, которые не противоречат ему. Например, -std = c90 отключает некоторые функции GCC, которые несовместимы с ISO C90, такие как ключевые слова asm и typeof, но не другие расширения GNU, которые не имеют значения в ISO C90, такие как исключение среднего срока a?: выражение.
GCC documentation for -std=

Расширение ##__VA_ARGS__ не противоречит стандарту. Что вызывает отклонение сайта coliru, так это то, что установлен флаг -pedantic.

Действительные программы ISO C и ISO C++ должны правильно компилироваться с этой опцией или без нее (хотя для некоторых редких требуется параметр -ansi или -std, определяющий требуемую версию ISO C). Однако без этой опции поддерживаются некоторые расширения GNU и традиционные функции C и C++. С помощью этой опции они отклоняются.
GCC documentation for -pedantic

+1

, но передавая' '' -std = C++ 14''' или любой стандарт удаляет это расширение даже в gcc, и поэтому пример coliru не компилирует – onqtam

+0

@onqtam: Это не то, что делает '-std'. См. Мое обновление. – jxh

+1

Используйте -std = gnu ++ 11 для повторного включения расширений GNU. – user3159253