Elad Benda
Elad Benda

Reputation: 36674

Unclear #define syntax in cpp using `\` sign

#define  is_module_error(_module_,_error_)    \
   ((_module_##_errors<_error_)&&(_error_<_module_##_errors_end))

#define  is_general_error(_error_)     is_module_error(general,_error_)
#define  is_network_error(_error_)     is_module_error(network,_error_)

Can someone please explain to me what does the first define means?

How is is evaluated?

I don't understand what's the \ sign mean here?

Upvotes: 1

Views: 117

Answers (1)

The backslash is the line continuation symbol used in preprocessor directives. It tells the preprocessor to merge the following line with the current one. In other words it escapes the hard newline at the end of the line.

In the specific example, it tells the preprocessor that

#define  is_module_error(_module_,_error_)    \
   ((_module_##_errors<_error_)&&(_error_<_module_##_errors_end))

should be interpreted as:

#define  is_module_error(_module_,_error_)  ((_module_##_errors<_error_)&&(_error_<_module_##_errors_end))

The relevant quote from the C99 draft standard (N1256) is the following:

6.10 Preprocessing directives

[...]

Description

A preprocessing directive consists of a sequence of preprocessing tokens that satisfies the following constraints: The first token in the sequence is a # preprocessing token that (at the start of translation phase 4) is either the first character in the source file (optionally after white space containing no new-line characters) or that follows white space containing at least one new-line character. The last token in the sequence is the first new-line character that follows the first token in the sequence. A new-line character ends the preprocessing directive even if it occurs within what would otherwise be an invocation of a function-like macro.

Emphasis on the relevant sentence is mine.

If you are also unsure of what the ## symbol means, it is the token-pasting operator. From the already cited C99 document (emphasis mine):

6.10.3.3 The ## operator

[...]

Semantics

If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a ## preprocessing token, the parameter is replaced by the corresponding argument’s preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker preprocessing token instead.

In the case at hand this means that, for example, wherever the preprocessor finds the following macro "call":

is_module_error(dangerous_module,blow_up_error)

it will replace it with this code fragment:

((dangerous_module_errors<blow_up_error)&&(blow_up_error<dangerous_module_errors_end))

Upvotes: 6

Related Questions