Nested #else handling in false #ifdef in C [duplicate] - c

I have a question about Pre-processor directives in c++:
For example:
#ifndef QUESTION
//some code here
#ifndef QUESTION
//some code here
#endif
#endif
Can we use it in this way, and can the C++ compiler match the ifndef and endif in the right way?

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 --------|

Yes, you can nest #if/#endif blocks. Some C coding styles would tell you to write
#ifdef CONDITION1
# ifdef CONDITION2
# endif
#endif
using spaces to denote the level of nesting.

In your code, the #ifndef QUESTION section will be discarded unless you #undef QUESTION.
Good luck!

Related

Can I do nesting of #ifdef? [duplicate]

I have a question about Pre-processor directives in c++:
For example:
#ifndef QUESTION
//some code here
#ifndef QUESTION
//some code here
#endif
#endif
Can we use it in this way, and can the C++ compiler match the ifndef and endif in the right way?
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 --------|
Yes, you can nest #if/#endif blocks. Some C coding styles would tell you to write
#ifdef CONDITION1
# ifdef CONDITION2
# endif
#endif
using spaces to denote the level of nesting.
In your code, the #ifndef QUESTION section will be discarded unless you #undef QUESTION.
Good luck!

Putting a #endif inside a #if

Is it possible to put a #endif inside a #if as the block's 'content' not as the pair #endif for the #if?
#if (SOME_CONDITION)
#if (ANOTHER_CONDITION)
#endif // pair endif for #if (SOME_CONDITION)
#if (SOME_CONDITION)
#endif // pair endif for #if (ANOTHER_CONDITION)
#endif // pair endif for #if (SOME_CONDITION)
If this is not possible how to conditionally compile a #if ... #endif pair?
This is what I was doing.
I was modifying a code base that we bought from another company. To compile it with and without my modifications easily I was using a macro say like shown below.
#if (MY_COMPANY_EDITS_ENABLED)
// My Modified code goes here
#else
// unmodified code from another company
#endif
In this way I could easily compile in/out my modifications while maintaining readability about my edits. I was using the same #if #else #endif blocks everywhere. But then I came across a code that is being compiled in, in the original unmodified code base, based on some macro value.
#if (FEATURE_A_IS_ENABLED)
// Line 1
// Line 2
#endif
But I want to compile this code [Line 1 and Line 2] regardless of the macro value FEATURE_A_IS_ENABLED
My first thought was to follow the same convention that I used till now [to maintain readability about my edits].
#if (MY_COMPANY_EDITS_ENABLED)
//#if (FEATURE_A_IS_ENABLED)
#else
#if (FEATURE_A_IS_ENABLED)
#endif
// Line 1
// Line 2
#if (MY_COMPANY_EDITS_ENABLED)
// #endif
#else
#endif
#endif
Then I realized this is not possible.
I know, alternative methods exist to achieve the same. But was wondering whether I could use the same convention
#if (MY_COMPANY_EDITS_ENABLED)
// My Modified code goes here
#else
// unmodified code from another company
#endif
in this case too.
No, it's not possible. The first #endif will be matched with the most recent #if or #else, so your code will be interpreted like this:
#if (SOME_CONDITION)
#if (ANOTHER_CONDITION)
#endif // pair endif for #if (ANOTHER_CONDITION)
#if (SOME_CONDITION)
#endif // pair endif for the second #if (SOME_CONDITION)
#endif // pair endif for the first #if (SOME_CONDITION)
This is not possible, as the preprocessor only does a single pass over your file, and the #endif gets matched with the preceding #if. If you want to make an #if/#endif block conditional, then just nest it inside another #if/#endif block:
#if CONDITION_A
# if CONDITION_B
...
# endif /* CONDITION_B */
#endif /* CONDITION_A */
Put another way, it's not possible to have preprocessing directives construct other preprocessing directives, as the output from the initial "construction" phase will not be reparsed by the preprocessor.
The (silly) example below wouldn't work either for example, even assuming the newlines wouldn't be an issue (which they would be here):
#if DEFINE_X_TO_FIVE
#define X
#endif
#if DEFINE_X_TO_FIVE
5
#endif
I recommend making the changes based on feature sets rather than whether or not they are yours or not then group them together to make a given version (MY_COMPANY_EDITS_ENABLED) or whatever:
#if (MY_COMPANY_EDITS_ENABLED)
#define FEATUREA
#define FEATUREB
#define FEATUREC
#define FEATURED
#else
#define FEATUREA
#undef FEATUREB
#undef FEATUREC
#undef FEATURED
#endif
#ifdef FEATUREA
//do some feature A stuff
#endif
// do code
#ifdef FEATUREB
//do some feature B stuff
#endif
#ifndef FEATUREC
//do some stuff if not feature C
#endif
// etc...
This is a lot more flexible in the long run and lets you switch changes features on and off with a rebuild.
Off course you can nest your preprocessor directives:
#ifdef CONDITION1
// some code here
# ifdef CONDITION2
// some else here
# endif
#endif
But make sure to end each condition properly.
See also: http://www.ioccc.org/years.html#1995_vanschnitz and http://www.ioccc.org/years.html#2004_vik2

C Pre-Processor Conditional Directive Precedence and Nesting

I have some code that has an existing preprocessor conditional directives of the form:
#ifndef SYMBOL_XYZ
// some code here
#else
// some other code here
#endif
and I want to add a new condition that supersedes that logic, and I think this is the way to do it but I'm unsure of the subtleties around nesting and precedence when it comes to the C pre-processor.
#ifdef NEW_SYMBOL_ABC
// some new code here that takes precedence over the other two conditions
#else
#ifndef SYMBOL_XYZ
// some code here
#else
// some other code here
#endif
#endif
Do I have that right? Would it be equivalent to do:
#ifndef NEW_SYMBOL_ABC
#ifndef SYMBOL_XYZ
// some code here
#else
// some other code here
#endif
#else
// some new code here that takes precedence over the other two conditions
#endif
Try this .. .
#ifdef NEW_SYMBOL_ABC
// some new code here that takes precedence over the other two conditions
#elif !defined(SYMBOL_XYZ)
// some code here
#else
// some other code here
#endif
Above is what I commonly use and should work with gcc for sure.
Not sure, but should work with visual c++ and other compilers.

C: Preprocessor in Macros?

Is there a way to use preprocessor keywords inside of a macro? If there is some sort of escape character or something, I am not aware of it.
For example, I want to make a macro that expands to this:
#ifdef DEBUG
printf("FOO%s","BAR");
#else
log("FOO%s","BAR");
#endif
from this:
PRINT("FOO%s","BAR");
Is this possible, or am I just crazy (and I will have to type out the preprocessor conditional every time I want to show a debug message)?
You can't do that directly, no, but you can define the PRINT macro differently depending on whether DEBUG is defined:
#ifdef DEBUG
#define PRINT(...) printf(__VA_ARGS__)
#else
#define PRINT(...) log(__VA_ARGS__)
#endif
Just do it the other way around:
#ifdef DEBUG
#define PRINT printf
#else
#define PRINT log
#endif
You're not crazy, but you're approaching this from the wrong angle. You can't have a macro expand to have more preprocessor arguments, but you can conditionally define a macro based on preprocessor arguments:
#ifdef DEBUG
# define DEBUG_PRINT printf
#else
# define DEBUG_PRINT log
#endif
If you have variadic macros, you could do #define DEBUG_PRINTF(...) func(__VA_ARGS__) instead. Either way works. The second lets you use function pointers, but I can't imagine why you'd need that for this purpose.

Difference between preprocessor directives #if and #ifdef

What is the difference (if any) between the two following preprocessor control statements.
#if
and
#ifdef
You can demonstrate the difference by doing:
#define FOO 0
#if FOO
// won't compile this
#endif
#ifdef FOO
// will compile this
#endif
#if checks for the value of the symbol, while #ifdef checks the existence of the symbol (regardless of its value).
#ifdef FOO
is a shortcut for:
#if defined(FOO)
#if can also be used for other tests or for more complex preprocessor conditions.
#if defined(FOO) || defined(BAR)

Resources