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

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

  •  13-10-2022
  •  | 
  •  

Frage

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.

War es hilfreich?

Lösung

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.

Andere Tipps

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.:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top