How to pass string as prefix of defined macro - c

Is there any idea to pass C string as part of the defined macro like below code?
#define AAA_NUM 10
#define BBB_NUM 20
#define PREFIX_NUM(string) string##_NUM
int main()
{
char *name_a = "AAA";
char *name_b = "AAA";
printf("AAA_NUM: %d\n", PREFIX_NUM(name_a));
printf("BBB_NUM: %d\n", PREFIX_NUM(name_b));
return 0;
}
Expected output
AAA_NUM: 10
BBB_NUM: 20

As mentioned in other posts, you can't use run-time variables in the pre-processor. You could however create enum that way. Though it is usually not a good idea to generate identifiers with macros either, save for special cases like when maintaining an existing code base and you are limited in how much of the existing code you can/want to change. So it should be used as a last resort only.
The least bad way to write such macros would be by using a common design pattern called "X macros". These are used when it is important that code repetition should be reduced to a single place in the project. They tend to make the code look rather alien though... Example:
#define PREFIX_LIST(X) \
/* pre val */ \
X(AAA, 10) \
X(BBB, 20) \
X(CCC, 30) \
enum // used to generate constants like AAA_NUM = 10,
{
#define PREFIX_ENUMS(pre, val) pre##_NUM = (val),
PREFIX_LIST(PREFIX_ENUMS)
};
#include <stdio.h>
int main (void)
{
// one way to print
#define prefix_to_val(pre) pre##_NUM
printf("AAA_NUM: %d\n", prefix_to_val(AAA));
printf("BBB_NUM: %d\n", prefix_to_val(BBB));
// another alternative
#define STR(s) #s
#define print_all_prefixes(pre, val) printf("%s: %d\n", STR(pre##_NUM), val);
PREFIX_LIST(print_all_prefixes)
return 0;
}

A macro is only processed before compilation and not at runtime. Your code example does not work as you can see here.
Good practice (for example MISRA coding rules) recommend to use macros as little as possible since it is error prone.

Preprocessor works at compile time and here name_a and name_b are non constant, and even if they were (i.e. const char *str is a real constant in C++ but not in C), there is a literal substitution and the preprocessor does not know the contents of variables.
This works (notice that the parameter should be expanded by another macro in order to get a valid token):
#include <stdio.h>
#define AAA_NUM 10
#define BBB_NUM 20
#define _PREFIX_NUM(string) string##_NUM
#define PREFIX_NUM(string) _PREFIX_NUM(string)
int main(void)
{
#define name_a AAA
#define name_b BBB
printf("AAA_NUM: %d\n", PREFIX_NUM(name_a));
printf("BBB_NUM: %d\n", PREFIX_NUM(name_b));
return 0;
}

There is no way in C to create runtime symbols and use them. C is a compiled language and all symbols have to be known before the compilation.
The preprocessor (which do changes on the text level before the compilation) does not know anything about the C language.

Related

C: Is there a way to define a macro AND output some code in a single statement?

I would like to define a macro that would generate program text for me AND also set some non-string macro value. I know that including #define in another #define is not going to work so I'm trying to find a different way.
A simple example:
#include <stdio.h>
#define START_SYNTHETIC int SYNTHETIC_FUNCTION() {
#define END_SYNTHETIC return 0;}
#define SYNTHETIC_FUNCTION my_function
START_SYNTHETIC
printf("Hello from %s", "SYNTHETIC_FUNCTION");
END_SYNTHETIC
int main() {
my_function();
}
This code kinda works, it produces the following output:
Hello from SYNTHETIC_FUNCTION
There are two problems with it:
function name is not expanded and I just have "SYNTHETIC_FUNCTION" in the output. This is currently not critical but might be needed later on.
I dislike having three lines to start my synthetic function. The empty line inserted by autoformatter is especially irritating. Can I reduce this to just a single macro invocation?
Is there a way to define a macro AND output some code in a single statement?
No, in C macros can't define other macros.
function name is not expanded and I just have "SYNTHETIC_FUNCTION" in the output.
Sure it doesn't - it's inside a string literal. Macro replacement is not done inside a string literal.
Can I reduce this to just a single macro invocation?
I do not understand the point at all of this code. Just use __func__.
int my_function(void) {
printf("Hello from %s\n", __func__);
return 0;
}
or pass the name as a macro parameter:
#define SYNTHETIC(name) \
int name(void) { \
printf("Hello from %s\n", #name); \
printf("but really, just use __func__ anyway...: %s\n", __func__); \
return 0; \
}
SYNTHETIC(my_function)

How does #if macro work in C?

MyMacros.h:
int const TESTING = 1;
#define INFO(MSG) fprintf(stderr, "INFO :: %s\n", MSG);
MyProgram.c:
#if TESTING
INFO("File 'data.dat' opened correctly.");
#endif
The message isn't printed to the screen. However if I do this:
#if TESTING < 1
It works and prints the message. Hunh???
You are confusing preprocessing and compiling.
The line int const TESTING = 1; is not understood by C preprocessor, it doesn't know the value of TESTING. In fact, neither the C compiler can use that value at the compile time (unlike C++ with better support of const expressions).
It is common pattern in C to define constants using the #define directive (again, unlike C++):
#define TESTING 1
And note the absence of a semicolon at the end of this line. Semicolons are required by the compiler, not the preprocessor.

How do you test if two #defines are the same with the C preprocessor

I have a C program which has platform-specific defines for access to low-level hardware. On some platforms, two macros point to the same variable, on others they are different:
//Platform_One.h
#define FOO_PORT (io.portA)
#define BAR_PORT (io.portB)
//Platform_Two.h
#define FOO_PORT (io.portC)
#define BAR_PORT (io.portC) //same
I have some initializer code that is different based on whether the #defines are the same or not. Conceptually, I'd like code like this:
callback_struct_t callbacks[] = {
#if FOO_PORT == BAR_PORT //unfortunately invalid
{&FOO_PORT, handle_foo_bar_func},
#else
{&FOO_PORT, handle_foo_func},
{&BAR_PORT, handle_bar_func},
#endif
{0,0}
};
Is there a reliable way to test at compile time if two arbitrary macros have the same definition?
You cannot compare the preprocessor macros as strings. One possibility would be to put the hardware port address (e.g., via another macro in the platform-specific headers) into the #defines and then compare the addresses.
However, the easiest way might be to do the comparison of addresses in actual code, e.g.:
if (&FOO_PORT == &BAR_PORT) {
// populate callbacks with handle_foo_bar_func
} else {
// populate callbacks with handle_foo_func and handle_bar_func
}
While not done in pre-processor, the compiler may be able to optimise away the unused branch since the hardware addresses are likely compile-time constants.
With the gnu c processor it can be done with stringification: https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
You could do something like this:
#include <stdio.h>
#include <string.h>
#define FOO_PORT (io.portA)
#define BAR_PORT (io.portB)
//#define FOO_PORT (io.portC)
//#define BAR_PORT (io.portC)
#define XMACRO_TEST(macro_a, macro_b) MACRO_TEST(macro_a, macro_b)
#define MACRO_TEST(macro_a, macro_b) \
if(strcmp((#macro_a),(#macro_b)) == 0) { \
printf(#macro_a" == "#macro_b"\n"); \
} else { \
printf(#macro_a" != "#macro_b"\n"); \
} \
int main(int argc, char *argv[])
{
XMACRO_TEST(FOO_PORT, BAR_PORT)
return 0;
}
You can compare macros that evaluate to integers.
My understanding is you have three options:
change the macro logic
use numerical values for port number macros (are they physical addresses?)
fill the callback structure with c code as one of the comments suggets.
The last option seems to be the most favourable. With propper use of const, the calculation will be carried at complile time by most compilers, anyway.

Printing name and value of a macro

I have a C program with a lot of optimizations that can be enabled or disabled with #defines. When I run my program, I would like to know what macros have been defined at compile time.
So I am trying to write a macro function to print the actual value of a macro. Something like this:
SHOW_DEFINE(X){\
if( IS_DEFINED(X) )\
printf("%s is defined and as the value %d\n", #X, (int)X);\
else\
printf("%s is not defined\n", #X);\
}
However I don't know how to make it work and I suspect it is not possible, does anyone has an idea of how to do it?
(Note that this must compile even when the macro is not defined!)
As long as you are willing to put up with the fact that SOMESTRING=SOMESTRING indicates that SOMESTRING has not been defined (view it as the token has not been redefined!?!), then the following should do:
#include <stdio.h>
#define STR(x) #x
#define SHOW_DEFINE(x) printf("%s=%s\n", #x, STR(x))
#define CHARLIE -6
#define FRED 1
#define HARRY FRED
#define NORBERT ON_HOLIDAY
#define WALLY
int main()
{
SHOW_DEFINE(BERT);
SHOW_DEFINE(CHARLIE);
SHOW_DEFINE(FRED);
SHOW_DEFINE(HARRY);
SHOW_DEFINE(NORBERT);
SHOW_DEFINE(WALLY);
return 0;
}
The output is:
BERT=BERT
CHARLIE=-6
FRED=1
HARRY=1
NORBERT=ON_HOLIDAY
WALLY=
Writing a MACRO that expands to another MACRO would require the preprocessor to run twice on it.
That is not done.
You could write a simple file,
// File check-defines.c
int printCompileTimeDefines()
{
#ifdef DEF1
printf ("defined : DEF1\n");
#else // DEF1
printf ("undefined: DEF1\n");
#endif // DEF1
// and so on...
}
Use the same Compile Time define lines on this file as with the other files.
Call the function sometime at the start.
If you have the #DEFINE lines inside a source file rather than the Makefile,
Move them to another Header file and include that header across all source files,
including this check-defines.c.
Hopefully, you have the same set of defines allowed across all your source files.
Otherwise, it would be prudent to recheck the strategy of your defines.
To automate generation of this function,
you could use the M4 macro language (or even an AWK script actually).
M4 becomes your pre-pre-processor.
#ifdef MYMACRO
printf("MYMACRO defined: %d\r\n", MYMACRO);
#endif
I don't think what you are trying to do is possible. You are asking for info at runtime which has been processed before compilation. The string "MYMACRO" means nothing after CPP has expanded it to its value inside your program.
You did not specify the compiler you were using. If this is gcc, gcc -E may help you, as it stops after the preprocessing stage, and prints the preprocessing result. If you diff a gcc -E result with the original file, you may get part of what you want.
Why not simply testing it with the preprocessor ?
#if defined(X)
printf("%s is defined and as the value %d\n", #X, (int)X);
#else
printf("%s is not defined\n", #X);
#endif
One can also embed this in another test not to print it everytime:
#if define(SHOW_DEFINE)
#if defined(X)
printf("%s is defined and as the value %d\n", #X, (int)X);
#else
printf("%s is not defined\n", #X);
#endif
#endif
Wave library from boost can be helpful also to do what you want. If your project is big enough, I think it is worth trying. It is a C++ preprocessor, but they are the same any way :)
I believe what you are trying to do is not possible. If you are able to change the way your #defines work, then I suggest something like this:
#define ON 1
#define OFF 2
#define OPTIMIZE_FOO ON
#define OPTIMIZE_BAR OFF
#define SHOW_DEFINE(val)\
if(val == ON) printf(#val" is ON\n");\
else printf(#val" is OFF\n");
It is not possible indeed, the problem being the "not defined" part. If you'd relied on the macro values to activate/deactivate parts of your code, then you could simply do:
#define SHOW_DEFINE(X) \
do { \
if (X > 0) \
printf("%s %d\n", #X, (int)X); \
else \
printf("%s not defined\n", #X); \
} while(0)
Based on Chrisharris, answer I did this.
Though my answer is not very nice it is quite what I wanted.
#define STR(x) #x
#define SHOW_DEFINE(x) printf("%s %s\n", #x, strcmp(STR(x),#x)!=0?"is defined":"is NOT defined")
Only bug I found is the define must not be #define XXX XXX (with XXX equals to XXX).
This question is very close from Macro which prints an expression and evaluates it (with __STRING). Chrisharris' answer is very close from the answer to the previous question.
you can use an integer variable initialized to 1.
multiply the #define with this variable and print the value of variable.

using macros for configuration

I'm writing firmware in C for an embedded processor. I want to have all the configuration information in one header file called config.h. This is causing problems with the ADC initialization, where simple #defines won't do the trick. Right now the code is like so:
config.h
#define NUMBER_OF_POTS 1
#define POT_1_CHANNEL 27
adc.c
#define MAKE_CSS(channel) _CSS##channel
#define CALL_MAKE_CSS(channel) MAKE_CSS(channel)
void initialize_adc() {
CALL_MAKE_CSS(POT_1_CHANNEL);
}
What I want to do is not have to touch adc.c if I change config.h to:
#define NUMBER_OF_POTS 2
#define POT_1_CHANNEL 27
#define POT_2_CHANNEL 29
adc.c should just automatically add a second CALL_MAKE_CSS with some macro trickery.
I guess the question is: is there a trick that gives you for loop capability with a macro?
Thanks,
Steve.
I didn't test this:
// config.h
#define NUMBER_OF_POTS 2
extern int pots[];
// config.c
int pots[NUMBER_OF_POTS] = {
27,
29
};
// adc.c
void initialize_adc() {
for (int i = 0; i < NUMBER_OF_POTS; i++) {
CALL_MAKE_CSS(pots[i]);
}
}
You don't have to rely entirely on macros. Just define your 'magic numbers' as #defines.
For example:
In config.h:
#define NUMBER_OF_POTS 2
#define POT_1_CHANNEL 27
#define POT_2_CHANNEL 29
unsigned int PotChannelList[NUMBER_OF_POTS] = {POT_1_CHANNEL, POT_2_CHANNEL};
In adc.c:
for(i = 0; i < NUMBER_OF_CHANNELS; i++)
{
initialize_adc(PotChannelList[i]);
}
You still define the setup in config.h and don't have to change adc.c when you add a channel. You just add it to the list. The list order also defines the order of initialization.
EDIT: Sorry about the formatting mess...
Have a look at boost.preprocessor. Although boost is usually for C++, the preprocessor metaprogramming lib works, well, just with the CPP, so it may do what you want. It provides a few datastructures (lists, tuples) and iteration macros.
Sorry, I can't give you any example if it really does what you want, or at least provides another way, because I seldom needed it, and it's too long ago.
Note Just saw Schroeder's answer. Not relying on the PP if it is not necessary is still the best option...
The C preprocessor cannot do loops. You'll either have to do the looping in C code, or if you really need to do something loop-like at compile time, you can write your own preprocessor (which can just be a simple shell script, e.g.) that generates the necessary code.
Although you can't do loops with the preprocessor, you can do unrolled loops. So if you know you're never going to have more than 4 pots you could do this;
void initialize_adc() {
#if NUMBER_OF_POTS > 0
CALL_MAKE_CSS(POT_1_CHANNEL);
#endif
#if NUMBER_OF_POTS > 1
CALL_MAKE_CSS(POT_2_CHANNEL);
#endif
#if NUMBER_OF_POTS > 2
CALL_MAKE_CSS(POT_3_CHANNEL);
#endif
#if NUMBER_OF_POTS > 3
CALL_MAKE_CSS(POT_4_CHANNEL);
#endif
}
The only benefit of this compared to other solutions here is that there is no runtime overhead at all. Extra inline code "magically" appears if and only if another channel is added, just as the questioner wanted. To extract the ugliness from within the function call (at the cost of putting it earlier in your code instead), define 4 new macros each using the same #if NUMBER_OF_POTS > x technique. Then you'd be able to go simply;
void initialize_adc() {
INIT_CSS_1();
INIT_CSS_2();
INIT_CSS_3();
INIT_CSS_4();
}

Resources