Conditional macro definition to emulate default define - c

I'm working on some geometry-based code. The task at hand involves use of a bounding-box to contain the solid specimen. Now, in the code I have devised two different types of such boxes, namely INNER_BOUNDING_BOX and OUTER_BOUNDING_BOX. The code further expects use of any one of the two boxes, but not both. I'm trying to achieve it through the use of preprocessor.
I have written further code based on a couple of macros namely USE_INNER_BOUNDING_BOX and USE_OUTER_BOUNDING_BOX. I can ensure that at any time any one macro is defined through some simple construct like this:
#if defined(USE_INNER_BOUNDING_BOX) && defined(USE_OUTER_BOUNDING_BOX)
#undef USE_INNER_BOUNDING_BOX
#undef USE_OUTER_BOUNDING_BOX
#define USE_INNER_BOUNDING_BOX
#endif
#ifndef USE_INNER_BOUNDING_BOX
#ifndef USE_OUTER_BOUNDING_BOX
#define USE_INNER_BOUNDING_BOX
#endif
#endif
Now, if I wanted to use any particular box, I could just define the corresponding macro. The difficulty comes with wanting for use of a default setting macro say USE_DEFAULT_BOUNDING_BOX, which I could use to then set up define for any one of USE_INNER_BOUNDING_BOX or USE_OUTER_BOUNDING_BOX when both or none of them are explicitly defined.
I'd be inclined towards portable code, but compiler-specific trick could also pass. I'm using Visual Studio 2012.

Reliable one-of-many selections like those can better be done by selecting them with a single multi-value switch right away.
#define BOUNDING_INNER 1
#define BOUNDING_OUTER 2
/* default */
#define BOUNDING_BOX_TO_USE BOUNDING_INNER
/* alternatively please activate below line
#define BOUNDING_BOX_TO_USE BOUNDING_OUTER
*/
If you need to stay backward compatible to some configurations,
e.g. your code has already been used by others,
you can derive the single switch from the two, matching your default behaviour.
The advantage is to avoid #undef (in case you agree that it is an advantage to do so).
#if defined(USE_INNER_BOUNDING_BOX) && defined(USE_OUTER_BOUNDING_BOX)
#define BOUNDING_BOX_TO_USE BOUNDING_INNER
#endif
#ifndef USE_INNER_BOUNDING_BOX
#ifndef USE_OUTER_BOUNDING_BOX
#define BOUNDING_BOX_TO_USE BOUNDING_INNER
#endif
#endif
/* In case you are as paranoid a programmer as I am,
you might want to do some plausibility checking
here. ifndef, >0, <2 etc., triggering some #errors. */
/* Later, in code doing the actual implementation: */
#if (BOUNDING_BOX_TO_USE == BOUNDING_INNER)
/* do inner bounding stuff */
#endif
/* other code, e.g. common for inner and outer */
#if (BOUNDING_BOX_TO_USE == BOUNDING_OUTER)
/* do outer bounding stuff */
#endif

Since there are only two values I would use only one boolean variable:
#ifndef USE_OUTER_BOUNDING_BOX
#define USE_OUTER_BOUNDING_BOX 0
#endif
If USE_OUTER_BOUNDING_BOX is zero (false) the inner bounding box is used.
test.c:
#include <stdio.h>
#ifndef USE_OUTER_BOUNDING_BOX
#define USE_OUTER_BOUNDING_BOX 0
#endif
int main(void)
{
printf("%d\n", USE_OUTER_BOUNDING_BOX);
return 0;
}
Example:
$ cc -o test -DUSE_OUTER_BOUNDING_BOX=0 test.c
$ ./test
0
$ cc -o test -DUSE_OUTER_BOUNDING_BOX=1 test.c
$ ./test
1

Here is what I ended with:
// Comment to use bigger outer Bounding-Box
#define USE_INNER_BOUNDING_BOX
#define INNER_BOUNDING_BOX 0
#define OUTER_BOUNDING_BOX 1
#define DEFAULT_BOUNDING_BOX OUTER_BOUNDING_BOX
#if defined(USE_INNER_BOUNDING_BOX) && !defined(USE_OUTER_BOUNDING_BOX)
#define USE_BOUNDING_BOX INNER_BOUNDING_BOX
#elif defined(USE_OUTER_BOUNDING_BOX)
#define USE_BOUNDING_BOX OUTER_BOUNDING_BOX
#else
#define USE_BOUNDING_BOX DEFAULT_BOUNDING_BOX
#endif
#if (USE_BOUNDING_BOX == INNER_BOUNDING_BOX)
#undef USE_OUTER_BOUNDING_BOX
#define USE_INNER_BOUNDING_BOX
#else
#undef USE_INNER_BOUNDING_BOX
#define USE_OUTER_BOUNDING_BOX
#endif
This just works in this case. In case of more boxes, I'd append the conditional blocks.

Related

Using macro statement in macro function in C

Using #ifdef <macro> <statement> #endif allows one to have verbose messages displayed only during development and is quite handy. I wonder if something like the code below is possible, becoming even shorter:
// pseudo-code:
#define IN_DEV
#define DEBUG_ONLY(statement) (#ifdef IN_DEV (statement) #endif)
int main(void)
{
DEBUG_ONLY(printf("hello from debug mode\n");)
//...
}
This would only cost me a very readable one-liner which can be turned on or off. Is something like this / close to this possible?
You could change the meaning of DEBUG_ONLY dependent on if IN_DEV is defined:
// pseudo-code:
#ifdef IN_DEV
#define DEBUG_ONLY(statement) {statement}
#else
#define DEBUG_ONLY(statement) // Nothing
#endif
int main(void)
{
DEBUG_ONLY(printf("hello from debug mode\n");)
//...
}
Running example: Link
It doesn't make much sense to pass whole expressions as parameters to macros. That is both dangerous and unmaintainable. Worse yet, it's taking us down the obfuscation road of "lets invent our own private macro language instead of using readable C that anyone can understand". That's a terrible idea even for debugging purposes.
The more sensible approach would be a function-like printing macro which only prints something in debug build.
#ifdef INDEV
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
#else
#define DEBUG_PRINT(...)
#endif
int main(void)
{
DEBUG_PRINT("hello from debug mode\n");
}
Optionally this macro can be narrowed down to only accept strings and be made more type safe (C17 only):
#ifdef INDEV
#define DEBUG_PRINT(str) _Generic((str), char*: puts(str))
#else
#define DEBUG_PRINT(str) _Generic((str), char*: (void)0)
#endif
That is not possible. You cannot use #if inside a macro definition.
What you can do is this:
#define IN_DEV
#ifdef
#define DEBUG_ONLY(statement) (statement)
#else
#define DEBUG_ONLY(statement)
#endif
int main(void)
{
DEBUG_ONLY(printf("hello from debug mode\n");)
//...
}
This is also switchable with only a single macro IN_DEV.

How do I concatenate two string macros in C?

I am trying to implement VERSION macro for my program, that is to be changed under certain circumstances.
macro VERSION is defined via Makefile (git info is put there) and is a string.
Now I have a set of #define'd switches and I want VERSION to reflect which of them are on. This looks now like the follows (main.h):
#define COMPLEX_DEPOSITION // This is switch. later in code it is used in #ifdef...#endif construction.
#ifdef COMPLEX_DEPOSITION
#define CD "_COMP_DEP" // this is the string I want to put in the end of VERSION
#define VERSION_ VERSION CD
#undef VERSION // this is to suppress 'macro redefinition' warning
#define VERSION VERSION_
#undef VERSION_
#endif
Well, I get a lot of errors, most of which make me think that C preprocessor works with lines in file in random order:(
Later I have an even more complex thing that is intended to make VERSION -> VERSION_WLT_GAP_2
#define WIRESLIFETIMES
#ifdef WIRESLIFETIMES
#define GAP 2
#define VERSION_ (VERSION ## "_WLT_GAP_" ## #GAP)
#define VERSION VERSION_
#undef VERSION_
#endif
and I got no idea what to do and if this is even possible
String literals concatenate naturally when placed next to each other
"foo" "bar" is the same as "foobar".
As for the second example, you probably want:
#define CAT_(A,B) A##B
#define CAT(A,B) CAT_(A,B)
#define GAP 2
#define VERSION CAT(VERSION_WLT_GAP_ , GAP)
VERSION //expands to VERSION_WLT_GAP_2
I recommend playing with gcc -E/clang -E a bit, to learn how macros work,
before trying to compose anything complex with them.
Well, the answer seems to be the following:
// https://stackoverflow.com/questions/5256313/c-c-macro-string-concatenation
// Concatenate preprocessor tokens A and B without expanding macro definitions (however, if invoked from a macro, macro arguments are expanded).
#define PPCAT_NX(A, B) A ## B
// Concatenate preprocessor tokens A and B after macro-expanding them.
#define PPCAT(A, B) PPCAT_NX(A, B)
// Turn A into a string literal without expanding macro definitions (however, if invoked from a macro, macro arguments are expanded).
#define STRINGIZE_NX(A) #A
// Turn A into a string literal after macro-expanding it.
#define STR(A) STRINGIZE_NX(A)
#define COMPLEX_DEPOSITION
#ifdef COMPLEX_DEPOSITION
#define CD "_COMPDEP"
#else
#define CD ""
#endif
#define WIRESLIFETIMES
#ifdef WIRESLIFETIMES
#define GAP 2
#define WLT STR(PPCAT(_WLT:G, GAP))
#define DISABLE_METROPOLIS
#else
#define WLT ""
#endif
#define VERSION VERSIONX CD WLT
which produces V008.1-11-g68a9c89cb4-dirty_COMPDEP_WLT:G2 and I am happy with it.
Must be noted that I changed -DVERSION=... to -DVERSIONX=... inside Makefile

Enable/Disable LOG levels using C Macro

#include <stdio.h>
#define LOG_D(x) { printf("D:"); printf(x);}
#define LOG_E(x) { printf("E:"); printf(x);}
void test(void)
{
LOG_D("ALL is well " );
}
I have a very huge code it has different levels of log, like above code.
In the final tested library I just need only one error logs in order to reduce the code size .
so I want something like this
#define ENABLE_DEBUG_LOG 0
#define ENABLE_ERROR_LOG 1
#define LOG_D(x) {#if(ENABLE_DEBUG_LOG==1) printf("D:"); printf(x); #endif}
#define LOG_E(x) {#if(ENABLE_ERROR_LOG==1) printf("E:"); printf(x);#endif}
I added this #if(ENABLE_DEBUG_LOG==1) just for explaining, I need some solution which can compile.
Another option - you can just comment / uncomment ENABLE_DEBUG_LOG and ENABLE_ERROR_LOG to disable / enable corresponding log level.
// #define ENABLE_DEBUG_LOG // disable DEBUG_LOG
#define ENABLE_ERROR_LOG // enable ERROR_LOG
#ifdef ENABLE_DEBUG_LOG
#define LOG_D(x) { printf("D:"); printf(x);}
#else
#define LOG_D(x) // nothing
#endif
#ifdef ENABLE_ERROR_LOG
#define LOG_E(x) { printf("E:"); printf(x);}
#else
#define LOG_E(x) // nothing
#endif
You cannot nest preprocessor directives. But you can make two versions of your macro and define them in exclusive parts of an #if or #ifdef:
#define ENABLE_DEBUG_LOG 0
#if ENABLE_DEBUG_LOG != 0
#define LOG_D(...) printf("D: " __VA_ARGS__)
#else
#define LOG_D(...) // Do nothing
#endif
Here, the disabled version just "eats" the LOG_D macro and doesn't do anything. (Note that undefined macros are treated as the value 0 in #if conditionals.)
You should be able to do something like this:
#if ENABLE_DEBUG_LOG == 1
# define LOG_D(x) { printf("D:"); printf(x);}
#else
# define LOG_D(x)
#end
That way the debug log statements will just disappear if ENABLE_DEBUG_LOG is undefined or has a different value.
Regarding the other answers, it is not good idea to define the macros completely empty when they are not enabled, as this would go wrong when error logging is enabled:
if (some_error)
LOG_E("Oops...");
do_something();
If LOG_E(x) expands to nothing, then do_something() would only be called if some_error is true, which is probably not what you want!
So you could define the "do nothing" variant of LOG_E(x) like this:
#define LOG_E(x) { }
Rather than starting and ending with braces, I tend to use the do { blah; } while (0) construct as it forces you to put a semicolon on the end when you use it. Something like this:
#if ENABLE_ERROR_LOG
#define LOG_E(x) do { printf("E:"); printf(x); } while (0)
#else
#define LOG_E(x) do ; while (0)
#endif
Then,
if (some_error)
LOG_E("Oops")
would result in a syntax error because of the missing semicolon, forcing you to write it as
if (some_error)
LOG_E("Oops");
Another thing you can do is concatenate the "E:" or "D:" tag with the passed in string, although this requires the parameter to be a string literal, rather than a general char *:
#define LOG_E(x) printf("E:" x)
Another thing you can do is to define the macro with a variable number of parameters (a variadic macro) to increase your options:
#define LOG_E(...) printf("E:" __VA_ARGS__)
Then you can do:
if (some_error)
LOG_E("Oops, got error: %d\n", some_error);
Another thing you can do is let the compiler optimize out the call to printf and define it like this:
#define LOG_E(...) do if (ENABLE_ERROR_LOG) printf("E:" __VA_ARGS__); while (0)
A decent compiler will notice that the if condition is constant and either optimize out the call to printf completely (if the constant condition is false), or include it (if the constant condition is true). For some compilers, you might need to suppress warnings about constant conditions in an if statement.
I am not sure if this is what you want, but you could check the #ifdef directive.
#include <stdio.h>
/* #define DEBUG */
#ifdef DEBUG
#define LOG_D(x) { printf("D: %s\n",x); }
#define LOG_E(x) { printf("E: %s\n",x); }
#else
#define LOG_D(x)
#define LOG_E(x)
#endif
int main() {
LOG_D("blah...");
return 0;
}
If you uncomment the #define DEBUG line, the program will print D: blah...

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

Possible to #if or #ifdef based on preprocessor-generated "thing"

I'm trying to engage in some C-preprocessor-only templating efforts in order to type-specialize some code. I've tried to boil it down a bit, so this example seems trivial and pointless, but the real challenge is getting the "include" blocking.
Say I have a "template" file, that gets #included from other source files that define T_ELEMENT_TYPE before including the template.
// Template file...
#ifndef T_ELEMENT_TYPE
#error #define T_ELEMENT_TYPE
#endif
#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SYMBOLNAME EVALUATOR(SymbolFor, T_ELEMENT_TYPE)
#ifndef SYMBOLNAMEISDEFINED
#define SYMBOLNAMEISDEFINED EVALUTOR(DEFINEDFOR, T_ELEMENT_TYPE)
int SYMBOLNAME(T_ELEMENT_TYPE arg)
{
// do something with arg
return 0;
}
#endif // Guard #ifdef
Then I want to include that template from multiple instantiation sites, but I only want the templated function to be generated ONCE per unique T_ELEMENT_TYPE (so as not to create duplicate symbols.) Like, say this:
// Template-using file...
#define T_ELEMENT_TYPE int
#include "Template.c"
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE float
#include "Template.c"
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE int
#include "Template.c"
#undef T_ELEMENT_TYPE
int someOtherFunc()
{
int foo = 42;
foo = SymbolForint(foo);
float bar = 42.0;
bar = SymbolForfloat(bar);
return foo;
}
So I'm looking for something I can use in the template code. I imagined it might look something like this (although this does not work):
// Template file...
#ifndef T_ELEMENT_TYPE
#error #define T_ELEMENT_TYPE
#endif
#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SYMBOLNAME EVALUATOR(SymbolFor, T_ELEMENT_TYPE)
#ifndef SYMBOLNAMEISDEFINED
#define SYMBOLNAMEISDEFINED EVALUTOR(DEFINEDFOR, T_ELEMENT_TYPE)
int SYMBOLNAME(T_ELEMENT_TYPE arg)
{
// do something with arg
return 0;
}
#endif // Guard #ifdef
This particular incantation blocks ALL multiple instantiations of the template, not just for different values of T_ELEMENT_TYPE.
Is there a trick I can use to get this effect? Or am I just off the C-Preprocessor reservation, so to speak?
I think you're off the reservation. The first "argument" to #define, the macro name, isn't subject to macro-expansion. So I don't think the preprocessor can define a different symbol according to the value of T_ELEMENT_TYPE. Neither can the preprocessor construct a "list" of already-seen types and check for existence in that.
So I think the include-guard will have to be outside the file:
#ifndef included_mytemplatefile_h_int
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE int
#include "mytemplatefile.h"
#define included_mytemplatefile_h_int
#endif
Alternatively, if your template file header only declares the function SymbolFor_int, instead of defining it, then multiple inclusion isn't harmful. You could have a normal include guard around the parts of the file that don't depend on the current value of T_ELEMENT_TYPE, including the definitions of PASTER, EVALUATOR, SYMBOLNAME. You'd need a separate template file containing definitions, which the program (rather than each translation unit) needs to have exactly once:
template_%.c :
echo "#define T_ELEMENT_TYPE $*" > $#
echo "#include \"mytemplatedefinitions.c\"" >> $#
Then add template_int.o to the list of files linked into your program.

Resources