Будет ли использование директивы препроцессора для определения того, что символ доллара представляет конфликт?

Могу ли я использовать следующее в C ++?:

#define $ cout

int main(){
$<<"Hello World!\n";
return 0;
}

Мне интересно, не вызовет ли это каких-либо конфликтов.

6

Решение

Это не совсем законно, но ваша реализация может принять это.

Рассматривать:

[C++11: 2.5/1]: Каждый токен предварительной обработки, который конвертируется в токен (2.7), должен иметь лексическую форму ключевого слова, идентификатора, литерала, оператора или пунктуатора.

Здесь ваш $ очевидно, не является ключевым словом, оператором или пунктуатором (так как они перечислены в стандарте), и не выглядит как литерал, так что это может быть только идентификатор; теперь идентификаторы должен содержат только буквенно-цифровые и подчеркивания, и цифры не могут быть начальными (на основе грамматики, обозначенной как [C++11: 2.11]).

Тем не менее, стандарт также позволяет реализациям принимать Другой символы, поэтому то, что вы хотите сделать, может работать, но оно не будет переносимым.

10

Другие решения

Это поведение, определяемое реализацией. $ не входит в грамматику для идентификаторов правила для имен идентификаторов в C ++ являются:

  1. Не может начинаться с цифры
  2. Может состоять из букв, цифр, подчеркивания, универсальных имен символов и реализация определена персонажи
  3. Не может быть ключевое слово.

Но это позволяет определяемые реализацией символы которые многие компиляторы поддерживают как расширение, в том числе НКУ а также Visual Studio.

Фактическая грамматика рассматривается в проект стандарта C ++ раздел 2.11 Indentifier:

identifier:
identifier-nondigit            <- Can only start with a non-digit
identifier identifier-nondigit <- Next two rules allows for subsequent
identifier digit               <-  characters to be those outlined in 2 above
identifier-nondigit:
nondigit                       <- a-z, A-Z and _
universal-character-name
other implementation-defined characters
[...]

Мы можем видеть, что это относится к define из раздела 16 Директивы предварительной обработки. Из грамматики видно, что это должно быть идентификатор:

# define identifier replacement-list new-line
# define identifier lparen identifier-listopt) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list, ... ) replacement-list new-line
^^^^^^^^^^
3

Забавная ситуация с некоторыми компиляторами, которые позволяют использовать $ в идентификаторах. Например как минимум MS VC ++ 2010 позволяет использовать $ в идентификаторах.

Так что если, например, вы определили

char $ = '$';

а потом написал

#define $ std::cout
//...

$ << $;

тогда вместо символа $ вы увидите в консоли вывод № 1 или какое-то целое число. 🙂

0
По вопросам рекламы [email protected]