Can #If Pre-Processor Directives Be Nested in C++

Can #if pre-processor directives be nested in C++?

Yes, we can. The #endif statement matches to the previous #if #ifdef or #ifndef etc for which there hasn't been a corresponding #endif.

e.g.

#if  ----------|
#if -----| |
#endif ---| |
#endif --------|

Can C# preprocessor directives be nested?

Yes, they can be nested.

#define A
#define B

void Main()
{
#if A
#if B
Console.WriteLine("A and B");
#else
Console.WriteLine("A and not B");
#endif
#else
#if B
Console.WriteLine("B and not A");
#else
Console.WriteLine("neither A nor B");
#endif
#endif
}

Outputs:

A and B

Here's a .NET Fiddle for you to try.

You can comment out the two lines at the top individually to get different results, like:

#define A
// #define B

Outputs:

A and not B

Here's the same code with indentation that makes it clearer, though I would not indent the code like this. Overuse of conditional directives like this is a code smell in my opinion.

#define A
// #define B

void Main()
{
#if A
#if B
Console.WriteLine("A and B");
#else
Console.WriteLine("A and not B");
#endif
#else
#if B
Console.WriteLine("B and not A");
#else
Console.WriteLine("neither A nor B");
#endif
#endif
}

Can you nest C preprocessor directives?

Though your syntax is invalid, the answer to your question is technically yes. But it can only be accomplished by nasty tricks that make your code unreadable and unmaintainable.

See also: http://www.ioccc.org/years.html#1995_vanschnitz and http://www.ioccc.org/years.html#2004_vik2

Can the pre-processor directives like #include be placed only at the top of the program code?

An #include directive can be placed anywhere in a source file, but in C an identifier can usually not be used before it has been declared. That's the reason why you put the #include directive at the begining of your source file.

void foo(void)
{
printf("Hello world\n");
}

extern int printf(const char *, ...); // Error, the declaration should be put
// before the actual call

Pre-processor Directives (#if and #endif) not working in C

This preprocessor check

#if a
...
#endif

is performed at compile time and is completely unrelated to

int a;

For #if a to be true you need a previous statement such as

#define a 42

For #if a to be false you need a previous statement such as

#define a 0

However if you simply have

#define a

which in itself is valid, but does not define a testable value, then the compiler will issue an error like

error C1017: invalid integer constant expression

But having #define a 42 means you cannot then use a to define a variable because

int a;

will expand to

int 42;

which is an error.

C++ nested preprocessor directions

You can't have a #if inside a #define, but you can have a #define inside the code controlled by a #if.

For example:

#ifdef DEBUG

#define BINARY_VECTOR_RETURN_OPERATOR(optype) \
first-part \
debug-code \
last-part

#else

#define BINARY_VECTOR_RETURN_OPERATOR(optype) \
first-part \
last-part

#endif

If first-part and last-part are big enough, you might want to define macros for them.

I'm not saying this is a good idea, but it does do what you were trying to do.

EDIT: Thanks to @okorz001 for suggesting a cleaner alternative in a comment:

#ifdef DEBUG
#define DEBUG_CODE (blah, blah)
#else
#define DEBUG_CODE /* nothing */
#endif

#define BINARY_VECTOR_RETURN_OPERATOR(optype) \
first-part \
DEBUG_CODE;
last-part

Obviously the real code would use better names.

How do you indent preprocessor statements?

Just because preprocessing directives are "normally" not indented is not a good reason not to indent them:

#ifdef __WIN32__
#include <pansen_win32>
#else
#include <..>
#ifdef SOMEOTHER
stmts
#endif
maybe stmts
#endif

If you frequently have multiple levels of nesting of preprocessing directives, you should rework them to make them simpler.



Related Topics



Leave a reply



Submit