How to include filename created by a macro - c
I have the following define:
#define MY_CLASS MyClass
I'm trying to make a macro that will use MY_CLASS to expand to:
#include "MyClass.h"
Something like (according to this answer):
#define MY_CLASS MyClass
#define FILE_EXT h
#define M_CONC(A, B) M_CONC_(A, B)
#define M_CONC_(A, B) A##B
#define APP_BUILD M_CONC(MY_CLASS, M_CONC(.,FILE_EXT))
#include APP_BUILD
That one doesn't work though... I get these 3 errors:
Expected "FILENAME" or <FILENAME>
Pasting formed '.h', an invalid preprocessing token
Pasting formed 'MyClass.', an invalid preprocessing token
Is it possible to do it somehow?
As to your Question: If there's a more elegant / quicker (maybe 1 less macro definition?) solution
#define STRINGIFY(X) #X
#define FILE_H(X) STRINGIFY(X.h)
//usage:
#define MY_CLASS MyClass
#include FILE_H(MY_CLASS)
//expands to: #include "MyCLass.h"
//or
#define ANOTHER_CLASS AnotherClass
#include FILE_H(ANOTHER_CLASS)
//expands to: #include "AnotherClass.h"
Well, if you need concatenation, then you have to add two extra lines:
#define CONCAT(A,B) CONCAT_(A,B)
#define CONCAT_(A,B) A##B
//could be extended like this:
//#define CONCAT3(A,B,C) CONCAT(CONCAT(A,B),C)
//...
I was referred to this post in the comments (thanks #sj95126) which I originally missed. It didn't work as-is but I was able to deduce the right answer from it rather quickly...
This works:
#define MY_CLASS MyClass
#define EMPTY
#define MACRO1(x) #x
#define MACRO2(x, y) MACRO1(x##y.h)
#define MACRO3(x, y) MACRO2(x, y)
#include MACRO3(EMPTY, MY_CLASS)
If there's a more elegant / quicker (maybe 1 less macro definition?) solution I would be happy accept a different answer.
Related
#ifdef inside a #define?
I'm initializing an array of structures with the help of a define like this: #define FLAGCODE(name) { #name, MNT_ ## name } struct { const char *name; uint64_t flag; } flagcodes[] = { FLAGCODE(ACLS), FLAGCODE(ASYNC), ... This works nicely, and now I'd like to add a check, whether each flag (such as MNT_ACLS) is defined without inserting an #ifdef and #endif for each symbol by hand? That is, I want the macro FLAGCODE(name) to expand into (an equivalent of): #ifdef MNT_ ##name { # name, MNT_ ##name }, #endif Exempli gratia, if name is NOATIME, the code shall become: #ifdef MNT_NOATIME { "NOATIME", MNT_NOATIME }, #endif Yes, I realize, that this would mean double pass through preprocessor, and so is unlikely to be possible -- without a custom code-generator... But still...
There is a solution but highly not recommended! You could do funny things with C-preprocessor (cf. Macro to replace nested for loops and links in the question). But I repeat it: Don't do it. It is a cpp abuse. In two words, you have to create your own #ifdef with macro. In the code below, ISDEF is an "operator" to check if the flag is defined and #if has been redefined: IIF (To understand, all explanations are here: https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms) #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ #define COMMA , #define IIF(c) PRIMITIVE_CAT(IIF_, c) #define IIF_0(t, ...) __VA_ARGS__ #define IIF_1(t, ...) t #define CHECK_N(x, n, ...) n #define CHECK(...) CHECK_N(__VA_ARGS__, 0,) #define PROBE(x) x, 1, #define ISDEF(x) CHECK(PRIMITIVE_CAT(ISDEF_, x)) #define ISDEF_ PROBE(~) #define FLAGCODE(name) IIF(ISDEF(name))({ #name COMMA MNT_ ## name }COMMA) #define ACLS #define FLAGDEFINED int main() { struct { const char *name; uint64_t flag; } flagcodes[] = { FLAGCODE(ACLS) FLAGCODE(ASYNC) FLAGCODE(FLAGDEFINED) FLAGCODE(FLAGNOTDEFINED) ... You could also do a list with your flags (cf. MAP part in http://jhnet.co.uk/articles/cpp_magic). Enjoy but do not go overboard with preprocessor. Following the very good comment of Chris Dodd, 1 : This tricks works if the flag is define as empty (#define FLAGDEFINED). It does not work with, for example, #define FLAGDEFINED 1 or #define FLAGDEFINED xxx. 2 : CPP_ prefix has been added and name is changed by CPP_FLAG #define CPP_PRIMITIVE_CAT(CPP_a, ...) CPP_a ## __VA_ARGS__ #define CPP_COMMA , #define CPP_IIF(CPP_c) CPP_PRIMITIVE_CAT(CPP_IIF_, CPP_c) #define CPP_IIF_0(CPP_t, ...) __VA_ARGS__ #define CPP_IIF_1(CPP_t, ...) CPP_t #define CPP_CHECK_N(CPP_x, CPP_n, ...) CPP_n #define CPP_CHECK(...) CPP_CHECK_N(__VA_ARGS__, 0,) #define CPP_PROBE(CPP_x) CPP_x, 1, #define CPP_ISDEF(CPP_x) CPP_CHECK(CPP_PRIMITIVE_CAT(CPP_ISDEF_, CPP_x)) #define CPP_ISDEF_ CPP_PROBE(~) #define CPP_FLAGCODE(CPP_FLAG) CPP_IIF(CPP_ISDEF(CPP_FLAG))({ #CPP_FLAG CPP_COMMA MNT_ ## CPP_FLAG }CPP_COMMA) #define ACLS #define FLAGDEFINED
C Preprocessor: Stringify int with leading zeros?
I've seen this topic which describes the "stringify" operation by doing: #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) #define MAJOR_VER 2 #define MINOR_VER 6 #define MY_FILE "/home/user/.myapp" STR(MAJOR_VER) STR(MINOR_VER) Is it possible to stringify with leading zeros? Let's say my MAJOR_REV needs to be two characters "02" in this case and MINOR_REV 4 characters "0006" If I do: #define MAJOR_VER 02 #define MINOR_VER 0006 The values will be treated as octal elsewhere in the application, which I don't want.
No clean nor handy way to do it. Just as a challenge, here a possible "solution": 1) create a header file (e.g. "smartver.h") containing: #undef SMARTVER_HELPER_ #undef RESVER #if VER < 10 #define SMARTVER_HELPER_(x) 000 ## x #elif VER < 100 #define SMARTVER_HELPER_(x) 00 ## x #elif VER < 1000 #define SMARTVER_HELPER_(x) 0 ## x #else #define SMARTVER_HELPER_(x) x #endif #define RESVER(x) SMARTVER_HELPER_(x) 2) In your source code, wherever you need a version number with leading zeroes: #undef VER #define VER ...your version number... #include "smartver.h" at this point, the expression RESVER(VER) is expanded as a four-digit sequence of character, and the expression STR(RESVER(VER)) is the equivalent string (NOTE: I have used the STR macro you posted in you answer). The previous code matches the case of minor version in your example,it's trivial to modify it to match the "major version" case. But in truth I would use a simple external tool to produce the required strings.
I believe in the example provided by the question sprintf is the correct answer. That said, there are a few instances where you really want to do this and with C preprocessor if there is a will and somebody stupid enough to write the code there is typically a way. I wrote the macro FORMAT_3_ZERO(a) which creates a three digit zero padded number using brute force. It is in the file preprocessor_format_zero.h found at https://gist.github.com/lod/cd4c710053e0aeb67281158bfe85aeef as it is too large and ugly to inline. Example usage #include "preprocessor_format_zero.h" #define CONCAT_(a,b) a#b #define CONCAT(a,b) CONCAT_(a,b) #define CUSTOM_PACK(a) cp_ ## a __attribute__( \ (section(CONCAT(".cpack.", FORMAT_3_ZERO(a))), \ aligned(1), used)) const int CUSTOM_PACK(23);
Stringify first level macro expansion C
Is it possible to stringify this C macro: #define GPIO_INT_PIN (GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5) using something like MY_STRINGFY(GPIO_INT_PIN) to get "(GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5)" ?
Yes it is possible. Read about stringizing in GCC cpp documentation. #define STRINGIFY(It) #It #define MY_STRINGIFY(It) STRINGIFY(It) I corrected my answer thanks to Wojtek Surowka's one then use MY_STRINGIFY(GPIO_PORT_D|GPIO_PIN_IRQ_RISING|GPIO_PIN5) which would work much better if you use an enum to define the constants, e.g. enum Gpio_stuff_en { GPIO_PORT_D=5, GPIO_PIN_IRQ_RISING=17, GPIO_PIN5=23 }; Of course that won't work as you want if you need GPIO_PORT_D to be a macro, .e.g. because it expands to some non-constant-literal expression (like a variable, or an access to a field of some global structure, etc....) As a counter-example: #define FOO 1 #define BAR 2 #define STRINGIFY(s) #s #define MY_STRINGIFY(s) STRINGIFY(s) MY_STRINGIFY(FOO|BAR) is expanded to "1|2" not to "FOO|BAR", if your remove the two #define-s for FOO and for BAR and replace them with enum { FOO=1, BAR=2 }; you really get the expansion "FOO|BAR" as you want. Check with gcc -C -E ... Also: enum {FOO=1, BAR=2}; #define FOOORBAR (FOO|BAR) #define STRINGIFY(s) #s #define MY_STRINGIFY(s) STRINGIFY(s) MY_STRINGIFY(FOOORBAR) is expanded as "(FOO|BAR)" . But if you use #define for FOO and for BAR you get the "(1|2)" expansion. Maybe you could add in your own header, after including the external header defining GPIO_PORT_D etc... as a literal constants, something like : enum {en_GPIO_PORT_D= GPIO_PORT_D, en_GPIO_PIN_IRQ_RISING= GPIO_PIN_IRQ_RISING, en_GPIO_PIN5= GPIO_PIN5}; #undef GPIO_PORT_D #undef GPIO_PIN_IRQ_RISING #undef GPIO_PIN5 #define GPIO_PORT_D en_GPIO_PORT_D #define GPIO_PIN_IRQ_RISING en_GPIO_PIN_IRQ_RISING #define GPIO_PIN5 en_GPIO_PIN5 and then you'll get more readable stringified constants (but not exactly what you dream of).
If you have such two definitions #define STRINGIFY(s) #s #define MY_STRINGIFY(s) STRINGIFY(s) MY_STRINGIFY does what you want - expands its argument and adds quotes after.
How to write a while loop with the C preprocessor?
I am asking this question from an educational/hacking point of view, (I wouldn't really want to code like this). Is it possible to implement a while loop only using C preprocessor directives. I understand that macros cannot be expanded recursively, so how would this be accomplished?
If you want to implement a while loop, you will need to use recursion in the preprocessor. The easiest way to do recursion is to use a deferred expression. A deferred expression is an expression that requires more scans to fully expand: #define EMPTY() #define DEFER(id) id EMPTY() #define OBSTRUCT(id) id DEFER(EMPTY)() #define EXPAND(...) __VA_ARGS__ #define A() 123 A() // Expands to 123 DEFER(A)() // Expands to A () because it requires one more scan to fully expand EXPAND(DEFER(A)()) // Expands to 123, because the EXPAND macro forces another scan Why is this important? Well when a macro is scanned and expanding, it creates a disabling context. This disabling context will cause a token, that refers to the currently expanding macro, to be painted blue. Thus, once its painted blue, the macro will no longer expand. This is why macros don't expand recursively. However, a disabling context only exists during one scan, so by deferring an expansion we can prevent our macros from becoming painted blue. We will just need to apply more scans to the expression. We can do that using this EVAL macro: #define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) #define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) #define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) #define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__))) #define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__))) #define EVAL5(...) __VA_ARGS__ Next, we define some operators for doing some logic(such as if, etc): #define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ #define CHECK_N(x, n, ...) n #define CHECK(...) CHECK_N(__VA_ARGS__, 0,) #define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x)) #define NOT_0 ~, 1, #define COMPL(b) PRIMITIVE_CAT(COMPL_, b) #define COMPL_0 1 #define COMPL_1 0 #define BOOL(x) COMPL(NOT(x)) #define IIF(c) PRIMITIVE_CAT(IIF_, c) #define IIF_0(t, ...) __VA_ARGS__ #define IIF_1(t, ...) t #define IF(c) IIF(BOOL(c)) Now with all these macros we can write a recursive WHILE macro. We use a WHILE_INDIRECT macro to refer back to itself recursively. This prevents the macro from being painted blue, since it will expand on a different scan(and using a different disabling context). The WHILE macro takes a predicate macro, an operator macro, and a state(which is the variadic arguments). It keeps applying this operator macro to the state until the predicate macro returns false(which is 0). #define WHILE(pred, op, ...) \ IF(pred(__VA_ARGS__)) \ ( \ OBSTRUCT(WHILE_INDIRECT) () \ ( \ pred, op, op(__VA_ARGS__) \ ), \ __VA_ARGS__ \ ) #define WHILE_INDIRECT() WHILE For demonstration purposes, we are just going to create a predicate that checks when number of arguments are 1: #define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N #define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1) #define IS_1(x) CHECK(PRIMITIVE_CAT(IS_1_, x)) #define IS_1_1 ~, 1, #define PRED(x, ...) COMPL(IS_1(NARGS(__VA_ARGS__))) Next we create an operator, which we will just concat two tokens. We also create a final operator(called M) that will process the final output: #define OP(x, y, ...) CAT(x, y), __VA_ARGS__ #define M(...) CAT(__VA_ARGS__) Then using the WHILE macro: M(EVAL(WHILE(PRED, OP, x, y, z))) //Expands to xyz Of course, any kind of predicate or operator can be passed to it.
Take a look at the Boost preprocessor library, which allows you to write loops in the preprocessor, and much more.
You use recursive include files. Unfortunately, you can't iterate the loop more than the maximum depth that the preprocessor allows. It turns out that C++ templates are Turing Complete and can be used in similar ways. Check out Generative Programming
I use meta-template programming for this purpose, its fun once you get a hang of it. And very useful at times when used with discretion. Because as mentioned its turing complete, to the point where you can even cause the compiler to get into an infinite loop, or stack-overflow! There is nothing like going to get some coffee just to find your compilation is using up 30+ gigabytes of memory and all the CPU to compile your infinite loop code!
well, not that it's a while loop, but a counter loop, nonetheless the loop is possible in clean CPP (no templates and no C++) #ifdef pad_always #define pad(p,f) p##0 #else #define pad0(p,not_used) p #define pad1(p,not_used) p##0 #define pad(p,f) pad##f(p,) #endif // f - padding flag // p - prefix so far // a,b,c - digits // x - action to invoke #define n0(p,x) #define n1(p,x) x(p##1) #define n2(p,x) n1(p,x) x(p##2) #define n3(p,x) n2(p,x) x(p##3) #define n4(p,x) n3(p,x) x(p##4) #define n5(p,x) n4(p,x) x(p##5) #define n6(p,x) n5(p,x) x(p##6) #define n7(p,x) n6(p,x) x(p##7) #define n8(p,x) n7(p,x) x(p##8) #define n9(p,x) n8(p,x) x(p##9) #define n00(f,p,a,x) n##a(pad(p,f),x) #define n10(f,p,a,x) n00(f,p,9,x) x(p##10) n##a(p##1,x) #define n20(f,p,a,x) n10(f,p,9,x) x(p##20) n##a(p##2,x) #define n30(f,p,a,x) n20(f,p,9,x) x(p##30) n##a(p##3,x) #define n40(f,p,a,x) n30(f,p,9,x) x(p##40) n##a(p##4,x) #define n50(f,p,a,x) n40(f,p,9,x) x(p##50) n##a(p##5,x) #define n60(f,p,a,x) n50(f,p,9,x) x(p##60) n##a(p##6,x) #define n70(f,p,a,x) n60(f,p,9,x) x(p##70) n##a(p##7,x) #define n80(f,p,a,x) n70(f,p,9,x) x(p##80) n##a(p##8,x) #define n90(f,p,a,x) n80(f,p,9,x) x(p##90) n##a(p##9,x) #define n000(f,p,a,b,x) n##a##0(f,pad(p,f),b,x) #define n100(f,p,a,b,x) n000(f,p,9,9,x) x(p##100) n##a##0(1,p##1,b,x) #define n200(f,p,a,b,x) n100(f,p,9,9,x) x(p##200) n##a##0(1,p##2,b,x) #define n300(f,p,a,b,x) n200(f,p,9,9,x) x(p##300) n##a##0(1,p##3,b,x) #define n400(f,p,a,b,x) n300(f,p,9,9,x) x(p##400) n##a##0(1,p##4,b,x) #define n500(f,p,a,b,x) n400(f,p,9,9,x) x(p##500) n##a##0(1,p##5,b,x) #define n600(f,p,a,b,x) n500(f,p,9,9,x) x(p##600) n##a##0(1,p##6,b,x) #define n700(f,p,a,b,x) n600(f,p,9,9,x) x(p##700) n##a##0(1,p##7,b,x) #define n800(f,p,a,b,x) n700(f,p,9,9,x) x(p##800) n##a##0(1,p##8,b,x) #define n900(f,p,a,b,x) n800(f,p,9,9,x) x(p##900) n##a##0(1,p##9,b,x) #define n0000(f,p,a,b,c,x) n##a##00(f,pad(p,f),b,c,x) #define n1000(f,p,a,b,c,x) n0000(f,p,9,9,9,x) x(p##1000) n##a##00(1,p##1,b,c,x) #define n2000(f,p,a,b,c,x) n1000(f,p,9,9,9,x) x(p##2000) n##a##00(1,p##2,b,c,x) #define n3000(f,p,a,b,c,x) n2000(f,p,9,9,9,x) x(p##3000) n##a##00(1,p##3,b,c,x) #define n4000(f,p,a,b,c,x) n3000(f,p,9,9,9,x) x(p##4000) n##a##00(1,p##4,b,c,x) #define n5000(f,p,a,b,c,x) n4000(f,p,9,9,9,x) x(p##5000) n##a##00(1,p##5,b,c,x) #define n6000(f,p,a,b,c,x) n5000(f,p,9,9,9,x) x(p##6000) n##a##00(1,p##6,b,c,x) #define n7000(f,p,a,b,c,x) n6000(f,p,9,9,9,x) x(p##7000) n##a##00(1,p##7,b,c,x) #define n8000(f,p,a,b,c,x) n7000(f,p,9,9,9,x) x(p##8000) n##a##00(1,p##8,b,c,x) #define n9000(f,p,a,b,c,x) n8000(f,p,9,9,9,x) x(p##9000) n##a##00(1,p##9,b,c,x) #define n00000(f,p,a,b,c,d,x) n##a##000(f,pad(p,f),b,c,d,x) #define n10000(f,p,a,b,c,d,x) n00000(f,p,9,9,9,9,x) x(p##10000) n##a##000(1,p##1,b,c,d,x) #define n20000(f,p,a,b,c,d,x) n10000(f,p,9,9,9,9,x) x(p##20000) n##a##000(1,p##2,b,c,d,x) #define n30000(f,p,a,b,c,d,x) n20000(f,p,9,9,9,9,x) x(p##30000) n##a##000(1,p##3,b,c,d,x) #define n40000(f,p,a,b,c,d,x) n30000(f,p,9,9,9,9,x) x(p##40000) n##a##000(1,p##4,b,c,d,x) #define n50000(f,p,a,b,c,d,x) n40000(f,p,9,9,9,9,x) x(p##50000) n##a##000(1,p##5,b,c,d,x) #define n60000(f,p,a,b,c,d,x) n50000(f,p,9,9,9,9,x) x(p##60000) n##a##000(1,p##6,b,c,d,x) #define n70000(f,p,a,b,c,d,x) n60000(f,p,9,9,9,9,x) x(p##70000) n##a##000(1,p##7,b,c,d,x) #define n80000(f,p,a,b,c,d,x) n70000(f,p,9,9,9,9,x) x(p##80000) n##a##000(1,p##8,b,c,d,x) #define n90000(f,p,a,b,c,d,x) n80000(f,p,9,9,9,9,x) x(p##90000) n##a##000(1,p##9,b,c,d,x) #define cycle5(c1,c2,c3,c4,c5,x) n##c1##0000(0,,c2,c3,c4,c5,x) #define cycle4(c1,c2,c3,c4,x) n##c1##000(0,,c2,c3,c4,x) #define cycle3(c1,c2,c3,x) n##c1##00(0,,c2,c3,x) #define cycle2(c1,c2,x) n##c1##0(0,,c2,x) #define cycle1(c1,x) n##c1(,x) #define concat(a,b,c) a##b##c #define ck(arg) a[concat(,arg,-1)]++; #define SIZEOF(x) (sizeof(x) / sizeof((x)[0])) void check5(void) { int i, a[32769]; for (i = 0; i < SIZEOF(a); i++) a[i]=0; cycle5(3,2,7,6,9,ck); for (i = 0; i < SIZEOF(a); i++) if (a[i] != 1) printf("5: [%d] = %d\n", i+1, a[i]); }
Here's an abuse of the rules that would get it done legally. Write your own C preprocessor. Make it interpret some #pragma directives the way you want.
I found this scheme useful when the compiler got cranky and wouldn't unroll certain loops for me #define REPEAT20(x) { x;x;x;x;x;x;x;x;x;x;x;x;x;x;x;x;x;x;x;x;} REPEAT20( val = pleaseconverge(val) ); But IMHO, if you need something much more complicated than that, then you should write your own pre-preprocessor. Your pre-preprocessor could for instance generate an appropriate header file for you, and it is easy enough to include this step in a Makefile to have everything compile smoothly by a single command. I've done it.
How to escape an underscore in a C preprocessor token?
The following snippet is supposed to take the value of PROJECT (defined in the Makefile) and create an include file name. For example, if PROJECT=classifier, then it should at the end generate classifier_ir.h for PROJECTINCSTR I find that this code works as long as I am not trying to use an underscore in the suffix. However the use of the underscore is not optional - our code base uses them everywhere. I can work around this because there are a limited number of values for PROJECT but I would like to know how to make the following snippet actually work, with the underscore. Can it be escaped? #define PROJECT classifier #define QMAKESTR(x) #x #define MAKESTR(x) QMAKESTR(x) #define MAKEINC(x) x ## _ir.h #define PROJECTINC MAKEINC(PROJECT) #define PROJECTINCSTR MAKESTR(PROJECTINC) #include PROJECTINCSTR Edit: The compiler should try to include classifier_ir.h, not PROJECT_ir.h.
#define QMAKESTR(x) #x #define MAKESTR(x) QMAKESTR(x) #define SMASH(x,y) x##y #define MAKEINC(x) SMASH(x,_ir.h) #define PROJECTINC MAKEINC(PROJECT) #define PROJECTINCSTR MAKESTR(PROJECTINC)
This works for me: #define QMAKESTR(x) #x #define MAKESTR(x) QMAKESTR(x) #define MAKEINC(x) x ## _ir.h #define PROJECTINC(x) MAKEINC(x) #define PROJECTINCSTR MAKESTR(PROJECTINC(PROJECT)) #include PROJECTINCSTR
That barebone example works with gcc (v4.1.2) and tries to include "PROJECT_ir.h"