The directive of the #define preprocessor can define and override the macro. But its syntax is such that it is not clear what exactly it does (defines or overrides). In order to understand what it does, you need to take into account which preprocessor directives were executed earlier. It follows from this that a programmer who wants to define a macro may mistakenly override a macro that has been defined somewhere deep in the connected header file. This will lead to an error that is difficult to find. What code can strictly:

  • define macro
  • override macro

I wrote this code:

 #define safe_define(def, val) \ #ifdef def \ #error "DEFINED!" \ #else \ #define def val \ #endif // def 

The compiler generates an error on the first line of this code:

main.cpp | 17 | error: '#' is not followed by a macro parameter

  • Error in this code or in the caller? Show the 17th line - Anton Shchyrov
  • @Anton Shchyrov changed the question - Taras
  • line demolition to remove? - J. Doe
  • You cannot thrust preprocessor directives into a preprocessor directive, because they are processed in the same compilation step. Simply put, this is not possible if you want to avoid overriding, you have to write everywhere #ifndef / #define / #endif - Vladimir Pavluk

2 answers 2

its syntax is such that it is not clear what exactly it does

Clearly determines. If the specified is already defined somewhere, then a warning will be thrown (or an error if the compiler is told to consider warnings as errors).

The compiler generates an error on the first line of this code:

With the help of the #define directive it is impossible to define something that contains other preprocessor directives (except ## ). Therefore, your code is not going to.

And in order to check whether an existing macro is being redefined, even during the time of dinosaurs they came up with this method:

 #ifndef FOO # define FOO bar #endif 

Or:

 #ifdef FOO # undef FOO # define FOO bar #endif 

Or even:

 #ifdef FOO # error FOO must not be defined here! #endif 
  • "If the specified is already defined somewhere, it will not work to override it" - it will work out. #define A 5 #define A 6 - Taras
  • "If the specified is already defined somewhere, then the redefinition will not work." - not true. ideone.com/luTuiq - Qwertiy
  • And, I forgot that I just have an alias for gcc / g ++ with -Werror registered :) - PinkTux

In the second stage of preprocessing the source file, the line continuation characters are removed, and the adjacent lines are joined in one line.

From standard C ++ (2.2 Phases of translation)

  1. Each type of backslash character is automatically followed by a line-up. It can be eligible for being a part of such a line. If you want to use it, it’s not. This is not the end of a new character line. line character were appended to the file.

Only after this, the macros are processed at stage 4 (2.2 Phases of translation)

  1. Preprocessing directives are executed, macro invocations are expanded, and> _Pragma unary operator expressions are executed. If you are not in the world. It is also included in the process. All preprocessing directives are then deleted.

Given these quotes from the standard, your define directive is converted to

 #define safe_define(def, val) #ifdef def #error "DEFINED!" #else ... 

What is not a valid directive, as according to section 16 of Preprocessing directives

1 A preprocessing directive for the following constraints: a preprocessing directive tokens (4) white space containing no new-line characters The following is a new-line character that ends the preprocessing directive of a function-like macro.