I am used to handle defines like the following code snipped shows. The paramA is initialized with 1 (edit: defined as 1) and can be used in the code. So far so good...
#define paramA 1
int main(void)
{
int varTest1 = 0;
if(paramA < 2)
{
varTest1 = 1;
}
else
{
varTest1 = 2;
}
return 0;
}
Now I'm dealing with a code where I receive the following define:
#define ALGO_FEATURE ALGO_FEATURE_A
First question: What kind of type is "ALGO_FEATURE_A" ? What does here happen? Is it some kind of text define? Or is this even legal? It actually builds and seams to be valid from my point of view.
My goal is to react (I'm doing unittests with gTest) on different algo features with different tests. So if "ALGO_FEATURE" is "ALGO_FEATURE_A" I would like to call different tests than in case it is "ALGO_FEATURE_B".
Current approach looks like this (according to the first code snipped). But it does not work... No matter which one of the following versions. The result is always that the if condition is true.
First approach (while debugging it always run into the first option, even if the if conditions are switched.
#if (ALGO_FEATURE == ALGO_FEATURE_B)
EXPECT_TRUE(FALSE); // this line is always run, even if ALGO_FEATURE is not ALGO_FEATURE_B
#elif (ALGO_FEATURE == ALGO_FEATURE_A)
EXPECT_TRUE(TRUE); // this line is never reached even if it should be true
#endif
How can I adapt this approach ?
Thanks for your time !
CodePudding user response:
paramA is initialized with 1
No, paramA
is replaced by the source text 1
wherever it appears.
What kind of type is
ALGO_FEATURE_A
It isn't a type. Presumably it is itself a #define
, so ALGO_FEATURE
will be the same source text.
I would guess that both ALGO_FEATURE_A
and ALGO_FEATURE_B
are defined to 1
, so your tests are equivalent to
#if (1 == 1)
EXPECT_TRUE(FALSE); // this line is always run, even if ALGO_FEATURE is not ALGO_FEATURE_B
#elif (1 == 1)
EXPECT_TRUE(TRUE); // this line is never reached even if it should be true
#endif
You can't distinguish between something #defined to be one or the other of those if they are the same value. If there is an #if
around the definition of ALGO_FEATURE
, then you can use that, or you could #define IS_ALGO_FEATURE_A
, with the test
#if defined (IS_ALGO_FEATURE_B)
EXPECT_TRUE(FALSE);
#elif defined (IS_ALGO_FEATURE_A)
EXPECT_TRUE(TRUE);
#endif
CodePudding user response:
The C preprocessor does verbatim substitutions.
For instance
#define A B
if (A == B)
generates the code
if (B == B)
whatever that means.
If your purpose is variant code generation, you could use a construct like
// Available versions
#define BLUE 1
#define GREEN 2
// Desired version
#define VERSION BLUE // Or GREEN
#if VERSION == BLUE
// Blue code
#else
// Green code
#endif
This translates to
#if 1 == 1
// Blue code
#else
// Green code
#endif
so just
// Blue code
Extra remark:
if (VERSION == BLUE)
{
// Blue code
}
else
{
// Green code
}
Would probably have the same effect on optimized code, by dead branch elimination. (I am not recommending such a practice.)
CodePudding user response:
How to handle defines in C with pre processor instructions
A possibility is to use some other program to generate C code, or to generate test cases (or various test inputs).
Consider using GPP or GNU m4 to generate C code.
Perhaps you want to use GNU autoconf.
You certainly could use GNU make to build your program with partly generated C code.
Take inspiration from Qt. It does generate C code (in its moc
) and is an open source framework.
Maybe consider using POCO.
#define ALGO_FEATURE ALGO_FEATURE_A
The ALGO_FEATURE_A
might be provided elsewhere, e.g. if you compile with GCC invoked as gcc -Wall -DALGO_FEATURE_A
And your code could latter use preprocessor conditions like
#ifdef ALGO_FEATURE_A
/// some code
#endif