Evaluate constant before displaying it in preprocessor - c

On this site I found tricks to display constant values in preprocessor, like:
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
#define A 5
#pragma display(VAR_NAME_VALUE(A))
that generates the output A=5
and they work well, but when I need to evaluate something like:
#define A 5
#define B (A*5)
#pragma display(B)
it displays the output B=5*5.
What if I wanted to display B=25? How should I write the preprocessor directive to do this?

You can not, the macro replacement mechanism does not involve doing calculations, but you can take a look to GNU M4:
Besides just doing macro expansion, m4 has built-in functions for including named files, running shell commands, doing integer arithmetic, manipulating text in various ways, performing recursion, etc....
at built-in eval
http://www.gnu.org/software/m4/manual/m4.html#Eval

Related

Turning a type name into a single token with the C preprocessor

I want to concatenate a C type name after some identifier. That's straightforward if the type name consists of just one token. However, if it's for example long int, I'm not finding a working solution.
For example, this code:
#define ADDSUFFIX(X,Y) X ## Y
#define EVALADDSUFFIX(X,Y) ADDSUFFIX(X,Y)
#define COMBINE(X,Y) EVALADDSUFFIX(X,EVALADDSUFFIX(__,Y))
#define SIMPLETEST COMBINE(myid,long int)
#define XSTR(x) STR(x)
#define STR(x) #x
#pragma message "You get this: " XSTR(SIMPLETEST)
Provides this as output:
./testing.h:35:9: note: '#pragma message: You get this: myid__long int'
So, obviously, the whitespace is there, and I don't get a token, but a couple of tokens.
Is it possible to either remove the whitespace, or replace it with an underscore for example? (both solutions would be fine, either myid__longint or myid__long_int).
I think this is not possible without separating long and int into different arguments, while using __VA_ARGS__ in the preprocessor and probably an iterator technique to process all of them.
To do so, you can do your own (with a maximum of 2 tokens it may be easier than infinite, take a look at How to write a while loop with the C preprocessor? ) or use an external library like BOOST.
Edit
I found an interesting link about recursion with preprocessor which may help construct the macro.

how to use #ifdef inside a macro?'#' is not followed by a macro parameter

I take a project which written in c, and there are lots of Macros.
I want to use a new macro to check if the macro is activated or not.
But the symbol # is reserved in macro. How to fix my code? Thanks :)
#define CHECK_MACRO( macro )\
#ifdef macro
printf("defined "#macro"\n");\
#else
printf("not defined "#macro"\n");\
#endif
You cannot use preprocessor conditional directives inside a macro. Generally speaking, the solution is to turn that inside out: use conditional directives to define the macro differently in different cases. That will not work for a generic macro-test macro such as you propose, however, and it also is limited by the fact that it determines whether the condition holds at the point where the macro is defined, not the point where it is used.
You may perhaps take consolation in the fact that this was never going to work anyway, as a result of the fact the arguments to a function-like macro are expanded before being substituted into the macro's replacement text (except in a couple of special cases that don't apply to the key part of your code).
There are alternatives that could work if the possible values of all macros of interest are limited to short lists of tokens that may appear as or in identifiers. There different alternatives that might be adequate if you can choose a small subset of macros that you're interested in testing. There are no alternatives that do what you propose in its full generality, unless you count writing the conditional compilation directives directly, without a macro, which in fact is the usual way of going about it.
Side note - m4 preprocssor - history/legacy.
In the early days of Unix, the 'm4' processor was used for code generation. It has enhanced features of cpp (or may be cpp is a scaled down version of m4). Specially, it has better support for multi-line macros. It continue to be used in various packages.
Worth mentioning that adding a code generation to your code will make it more complex to maintain/debug.
For example: a.m4
define(`CHECK_MACRO', `
#ifdef $1
printf ("defined #$1\n") ;
#else
printf ("undef #$1\n") ;
#endif
')
#include <stdio.h>
void main(void)
{
CHECK_MACRO(FOO) ;
CHECK_MACRO(BAR) ;
}
Then build/run
m4 a.m4 > a.c
cc a.c
./a.out
undef #FOO
undef #BAR
cc a.c -DFOO
./a.out
defined #FOO
undef #BAR
Usually, the generation was integrated into Makefile with a rule
%.c: %.m4:
m4 -s $< > $#
The -s help track source code line number (it will compile error line number matching the a.m4 source file.

Dynamically prefix macro names with a variadic macro

Background
I've utilized a set of preprocessor macros from another question that allows me to prefix symbol names (enums, function names, struct names, etc) in my source, i.e.:
#include <stdio.h>
#define VARIABLE 3
#define PASTER(x,y) x ## _ ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define NAME(fun) EVALUATOR(fun, VARIABLE)
void NAME(func)(int i);
int main(void)
{
NAME(func)(123);
return 0;
}
void NAME(func)(int i)
{
printf("i is %d in %s.\n", i, __func__);
}
Problem
This works as expected, with the following output: i is 123 in func_3.
Edit
I would like this code:
#define NAME(SOME_MACRO_CONST) (123)
#define NAME(SOME_MACRO_CONST2) (123)
To expand to:
#define 3SOME_MACRO_CONST (123)
#define 3SOME_MACRO_CONST2 (123)
I realize the macro shouldn't start with a digit. In the final code I'll be using names like LIB_A_ and LIB_B_ as prefixes.
/Edit
However, if I attempt to do the same with macros as the arguments to my NAME variadic macro, it fails like so:
Re-using NAME macro:
Code
#define NAME(MY_CONST) (3)
Output
test.c:7:0: warning: "NAME" redefined
#define NAME(MY_CONST) 3
Manually pasting prefix:
Code:
#define VARIABLE ## MY_CONST (3)
Output:
test.c:8:18: error: '##' cannot appear at either end of a macro expansion
#define VARIABLE ## MY_CONST (3)
Question
How can I create simple macro definitions (name + value) that has a common prefix for all the macros? The goal is to be able to make multiple copies of the source file and compile them with different flags so all versions can be linked together into the same final binary without symbol/macro name collisions (the macros will later be moved into header files). The final file will be too big to write in something like M4 or a template language. Ideally, the solution would involve being able to use a single macro-function/variadic-macro for all use cases, but I'm OK with one macro for symbol prefixing, and another for macro-name prefixing.
I would like this code:
#define NAME(SOME_MACRO_CONST) (123)
#define NAME(SOME_MACRO_CONST2) (124)
To expand to:
#define 3SOME_MACRO_CONST (123)
#define 3SOME_MACRO_CONST2 (124)
(I corrected the second number to 124 to make it different from the first one, for readability purposes)
This is impossible with the C preprocessor
for several reasons:
3SOME_MACRO_CONST is not a valid identifier (both for the preprocessor, and for the C compiler itself) since it does not start with a letter or an underscore. So let's assume you want your code to be expanded to:
/// new desired expansion
#define THREE_SOME_MACRO_CONST (123)
#define THREE_SOME_MACRO_CONST2 (124)
this is still impossible, because the preprocessor works before anything else and cannot generate any preprocessor directive (e.g. #define).
A workaround, if you only want to #define some numbers (computable at compile-time !!!) might be to expand to some anonymous enum like
enum {
THREE_SOME_MACRO_CONST= 123,
THREE_SOME_MACRO_CONST2= 124,
};
and you know how to do that in the details. Read also about X-macros.
However, even if you can change your requirement to something that is possible, it might be not recommendable, because your code becomes very unreadable (IMHO). You could sometimes consider writing some simple script (e.g. in sed or awk ...), or use some other preprocessor like GPP, to generate a C file from something else.
Notice that most serious build automation tools (like GNU make or ninja) -or even IDEs (they can be configured to) permit quite easily (by adding extra targets, recipes, commands, etc...) to generate some C (or C++) code from some other file, and that meta-programming practice has been routinely used since decades (e.g. bison, flex, autoconf, rpcgen, Qt moc, SWIG ...) so I am surprised you cannot do so. Generating a header file containing many #define-s is so common a practice that I am surprised you are forbidden to do so. Perhaps you just need to discuss with your manager or colleagues. Maybe you need to look for some more interesting job.
Personally, I am very fond of such meta-programming approaches (I did my PhD on these in 1990, and I would discuss them at every job interview; a job where metaprogramming is forbidden is not for me. Look for example at my past GCC MELT project, and my future project also will have metaprogramming). Another way of promoting that approach is to defend domain specific languages (and the ability to make your DSL inside some large software project; for example the GCC compiler has about a dozen of such DSLs inside it....). Then, your DSL can (naturally) be compiled to C which is a common practice. On modern operating systems that generated C code could be compiled at runtime and dynamically loaded as a (generated) plugin (using dlopen on POSIX...)
Sometimes, you can trick the compiler. For a project compiled by GCC, you could consider writing your GCC plugin..... (that is a lot more work than adding a command generating C code; your plugin could provide extra magic pragmas or builtins or attributes used by some other macros).
You could also configure the spec file of your gcc to handle specifically some C files. Beware, that could affect every future compilation!

Conditionally use #warning or #pragma message or nothing

I have a code which uses #warning a lot to signal compile time branches to the user. The code has a lot of configuration option, therefore it is not really clear which bits of the code are actually taken into the compilation.
Once you have chosen the configuration options, those warnings really clutter the output. So I would like to be able to disable them. The easiest way would be wrapping each of those warnings into an #ifdef ... #else construct. But if I was to touch that code again, I need to go through the whole codebase again.
So instead I want to abstract this a bit. However, I am stuck trying to define a macro that calls #warning or #pragma message. The following compiles but does not do the right thing:
#ifdef EMIT_WARNINGS
#define WARNING(s) _Pragma("message(\"Hi\")")
#else
#define WARNING(s)
#endif
WARNING("How can I print this?")
All my attempts of putting s into there have failed. Once I do _Pragma("message(\"" s "\")"), I get that _Pragma expects a single parenthesised string.
Is there anything I can do to abstract this nicely?
All my attempts of putting s into there have failed. Once I do _Pragma("message(\"" s "\")"), I get that _Pragma expects a single parenthesised string.
_Pragma(S) has an effect equivalent to #pragma X, where X is the unstringified form of S. Going backwards, that means that to get the effect of #pragma X in a _Pragma call, you simply need to stringify X.
The fact that part of X is itself a string is misleading you... don't think of these as pieces you're assembling, but rather as a whole. Rather than trying to stringify s and put it inside "message(\"" and "\")", just stringify message(s) itself as a whole, like this:
#ifdef EMIT_WARNINGS
#define WARNING_I(s) _Pragma(#s)
#define WARNING(s) WARNING_I(message(s))
#else
#define WARNING(s)
#endif
WARNING("How can I print this?")
So when warnings are enabled, WARNING("How can I print this?") expands to WARNING_I(message("How can I print this")). That argument to WARNING_I is itself what you would put on a pragma line; it is your X. The definition of WARNING_I then stringifies that, making the correct S for _Pragma.
From https://gcc.gnu.org/onlinedocs/gcc-6.3.0/cpp/Diagnostics.html#Diagnostics
Neither ‘#error’ nor ‘#warning’ macro-expands its argument. Internal whitespace sequences are each replaced with a single space. The line must consist of complete tokens. It is wisest to make the argument of these directives be a single string constant; this avoids problems with apostrophes and the like.

Use macro expansion to create multiple #define constants

I am working on an open gl driver and need to define a set of constants using #define. The names of these constants iterate along with the value they represent. They are also bounded by a max value set by another #define which is hardware specific. I would like to define the these constants using the max value if possible.
Currently I have defined them as follows:
#define GL_MAX_TEXTURE_UNITS 24
#define GL_TEXTURE0 0
#define GL_TEXTURE1 1
...
#define GL_TEXTURE24 24
I would like to have something along the lines of the following:
#define GL_MAX_TEXTURE_UNITS 24
#define GL_TEXTURE(SOMETRICKYMACRO)
Where the macro is defined in such a way that at compilation I end up with an expansion equivalent to the first case but if I wanted to change the number of constants I would only need to modify GL_MAX_TEXTURE_UNITS.
The C preprocessor cannot produce new preprocessing directives itself. If you want to do something like this, you would need to generate the header file with a separate utility (perhaps a shell or awk script) as part of your build process.
If you find yourself really needing something like this (programmatically variable range of values), it might be an indication that referring to them symbolically via macro names is a bad design choice.

Resources