简体   繁体   中英

Is it possible to simulate the effect that place #ifdef inside another #ifdef #endif?

I was checking some import statement, and found some import statement is in the pattern like this:

#ifdef A

#ifdef B
//SOME SETTINGS 1 (some include,define,ifdef...)
#else
//SOME SETTINGS 2 (some include,define,ifdef...)
#endif

#else

#ifndef B
//SOME SETTINGS 1 (some include,define,ifdef...)
#else
//SOME SETTINGS 2 (some include,define,ifdef...)
#endif

#endif

which the macro of A is just inverse the macro of B,but "//SOME SETTINGS 1" and "//SOME SETTINGS 2" need to appear twice, so I try to rewrite that:

#ifdef A
#ifdef B
#else
#ifndef B
#endif

//SOME SETTINGS 1 (some include,define,ifdef...)

#else

//SOME SETTINGS 2 (some include,define,ifdef...)

#endif

but it failed to compile, is there any syntax to simulate this case that "//SOME SETTINGS 1" and "//SOME SETTINGS 2" only need to appear once?

Your problem is this:

#ifdef A
  #ifdef B
  #else
   #ifndef B
   #endif
           //SOME SETTINGS 1 (some include,define,ifdef...)
#else
          //SOME SETTINGS 2 (some include,define,ifdef...)

#endif

You have a mismathed number of #ifdefs, elses and endifs.

To do what you asked for:

#if (defined(A) && defined(B)) || (!defined(A) && !defined(B))
  // settings 1
#else
  // settings 2
#endif

This is how you generally approach these kind of problems. You set up a Karnaugh truth table:

A    B   => 1
A   !B   => 2
!A   B   => 2
!A  !B   => 1

Reading this table alound means you need to use settings 1 for when (A and B) are defined OR when (A is not defined and B is not defined)... hence in C:

(A && B) || (!A && !B)

Convert that to ifdef syntax and you're good to go.

Yes, you can use the defined operator (evaluates to 1 if the identifier is defined and 0 otherwise). You basically seem to want SOME SETTING 1 if A and B are defined or both undefined and SOME SETTINGS 2 otherwise:

#if defined(A) == defined(B)
//SOME SETTINGS 1 (some include,define,ifdef...)
#else
//SOME SETTINGS 2 (some include,define,ifdef...)
#endif

The direct comparision is because either you want defined(A) and defined(B) to be both one or both zero - and one and zero is the only alternatives for them.

Note that if you want to extend this to more than two alternatives you have to be careful to use #elif because SOME SETTINGS 1 can alter subsequent tests if you repeat #if - #endif groups - that's why we need to use #else for the SOME SETTINGS 2 part. For example:

#if COND1(A,B):
     // SOME SETTINGS 1
#elif COND2(A,B):
     // SOME SETTINGS 2
// etc
#else
     // DEFAULT SETTINGS
#endif

You can combine the checks for definition like this.

#if (defined(A) && defined(B)) || (!defined(A) && !defined(B))
// SOME SETTINGS 1
#else
// SOME SETTINGS 2
#endif

You want settings 1 when A & B are defined, or niether A or B are defined. This should do the trick:

#if (defined (A) && defined(B)) || (!defined (A) && !defined(B))
    //SOME SETTINGS 1 (some include,define,ifdef...)
#else
    //SOME SETTINGS 2 (some include,define,ifdef...)
#endif

What about this:

#if (defined A && defined B) || (!defined A && !defined B)
//SOME SETTINGS 1 (some include,define,ifdef...)
#else
//SOME SETTINGS 2 (some include,define,ifdef...)
#endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM