Will using a preprocessor directive to define what a dollar sign represents cause any conflicts?

StackOverflow https://stackoverflow.com/questions/21884985

  •  13-10-2022
  •  | 
  •  

Can I use the following in C++?:

#define $ cout

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

I'm wondering whether it will cause any conflicts.

有帮助吗?

解决方案

It's not definitively legal, but your implementation is allowed to accept it.

Consider:

[C++11: 2.5/1]: Each preprocessing token that is converted to a token (2.7) shall have the lexical form of a keyword, an identifier, a literal, an operator, or a punctuator.

Here, your $ is obviously not a keyword, operator or punctuator (as these are enumerated in the standard), and it doesn't look like a literal, so it could only be an identifier; now, identifiers must contain only alphanumerics and underscores, and digits cannot be leading (based on the grammar denoted under [C++11: 2.11]).

However, the standard does also allow implementations to accept other characters, so what you want to do may work, but it will not be portable.

其他提示

This is implementation defined behavior. $ is not included in grammar for an identifiers the rules for identifier names in C++ are:

  1. It can not start with a number
  2. Can be composed of letters, numbers, underscore, universal character names and implementation defined characters
  3. Can not be a keyword.

But it does allow for implementation-defined characters which many compilers support as an extension, including gcc and Visual Studio.

The actual grammar is covered in the draft C++ standard section 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
[...]

We can see this applies to define from section 16 Preprocessing directives. We can see from the grammar that it must be an identifier:

# 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
         ^^^^^^^^^^

There is a funny situation with some compilers that allow to use $ in identifiers. For example at least MS VC++ 2010 allows to use $ in identifiers.

So if for example you defined

char $ = '$';

and then wrote

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

$ << $;

then instead of symbol $ you will see in the console output number 1 or some integer number.:)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top