Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this parenthesis-free C preprocessor definition safe?

In my /usr/include directory, there are at least two variants of #define NULL 0 tailored for C++ code1:

#define NULL 0    // from rpc/types.h #define NULL (0)  // from libio.h 

I feel like there must be a counter-example where the first one would not be safe, but I was not able to produce it.

Otherwise, is there some compelling argument about why it would be safe to not include the parentheses in this case (e.g., an informal "proof of correctness")?


1 That is, without including the variant #define NULL ((void*)0), which is useful for C but invalid in C++.

like image 557
anol Avatar asked May 20 '15 09:05

anol


People also ask

What are preprocessor definitions in C?

Working of C Preprocessor. The C preprocessor is a macro preprocessor (allows you to define macros) that transforms your program before it is compiled. These transformations can be the inclusion of header files, macro expansions, etc. All preprocessing directives begin with a # symbol.

Why do we recommend the use of parentheses for formal arguments used in a macro definition?

The macro and its parameters should be enclosed in parentheses. When macro parameters or expression are not parenthesized, the intended logic may get disrupted after expanding the macro.

Why does C have a preprocessor?

The preprocessor provides the ability for the inclusion of header files, macro expansions, conditional compilation, and line control. In many C implementations, it is a separate program invoked by the compiler as the first part of translation.


1 Answers

There is no difference. The only operators with higher priority are ::, ++ and -- and they are not applicable on 0 nor (0).

The only funny difference I see is obfuscation :

#define NULL (0)  void f(int x) {   // Do something with x }  int main() {   f NULL; // This code compiles   return 0; } 
like image 105
Caduchon Avatar answered Sep 24 '22 15:09

Caduchon