C Preprocessor to compute product specific include - macros
I have to maintain C code that has both generic components and product specific components. I would like to simplify my code so that I have just one generic product.h file which has a structure like
#if (PRODUCT_ID == 1)
#define PRODUCT_NAME Product1
#else
#if (PRODUCT_ID == 2)
#define PRODUCT_NAME Product2
#else
#error "Unsupported product id"
#endif
#endif
Then, whenever I have a header foo.h which has product specific components, I would like to use syntax like this
#include "product.h"
#include PRODUCT_SPECIFIC_INCLUDE
where PRODUCT_SPECIFIC_INCLUDE should be derived from __FILE__ and PRODUCT_NAME macro in such a way that it would translate to
#include "Product1/foo.h"
that is, the product specific header file has the same filename as the generic file, but is located in a product specific folder, whose name is the value of PRODUCT_NAME macro.
It seems that whatever I try has preprocessor stringification issues. I can't be the first to want such a structure. What am I missing?
Update
Here is what I currently have for PRODUCT_SPECIFIC_INCLUDE which does not work
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
You can do something like
#define STR2(F) #F
#define STR(F) STR2(F)
#define MAKE_PRODUCT_INCLUDE(FILE) STR(PRODUCT_SPECIFIC/FILE)
#include MAKE_PRODUCT_INCLUDE(foo.h)
but I don't know a way to avoid repeating the file name. Using __FILE__ gives a string and there is no way that I know to concatenate strings in the preprocessor (the fact that juxtaposed strings are concatenated is a parser feature, and ## is not usable for that "foo""bar" is not the spelling of a valid token).
The first code could be reduced to:
#if (PRODUCT_ID == 1)
#define PRODUCT_NAME Product1
#elif (PRODUCT_ID == 2)
#define PRODUCT_NAME Product2
#else
#error "Unsupported product id"
#endif
Secondly, you are trying to get the required include header name but the problem is in these two lines:
#define TOKENPASTE(x, y) x ## y
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
__FILE__ : This macro expands to the name of the current input file,
in the form of a C string constant
TOKENPASTE(PRODUCT_SPECIFIC, __FILE__) |--> product ## "foo.h"
product and " can never give a valid token. And that's why the CPP gives you error. What you need is writing the filename as plaintext so you can combine it with other macros.
You can do it like this:
#define TOKENPASTE(x) #x
#define TOKENPASTE2(x) TOKENPASTE(x)
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC/foo.h)
#include PRODUCT_SPECIFIC_INCLUDE
Related
cmph Minimal perfect hashing
I've spent days trying to make the library work on my system. The library has several algorithms which generate MPHFs. My understanding of minimal hash function is, that when I hash two distinct keys using the MPHF, they'll return two different ids. This does not seem to be the case with the 2 million keys that I've generated (integers, read as string by the algorithm). I've tried couple of algorithms that the library implements but all of them result in duplicate 'ids' for a lot of keys. Here is what I've written: #include <cmph.h> #include <iostream> #include <fstream> #include <bitset> #include <string> #include <sstream> #include <limits.h> using namespace std; int main(int argc, char** argv){ FILE *fp = fopen("keys.txt", "r"); FILE *read = fopen("keys2.txt", "r"); ofstream ids("ids2.txt"); if(!fp || !read || !ids.is_open()){ cerr<<"Failed to open the file\n"; exit(1); } cmph_t* hash = NULL; // source of keys cmph_io_adapter_t *source = cmph_io_nlfile_adapter(fp); cmph_config_t *config = cmph_config_new(source); cmph_config_set_algo(config, CMPH_BDZ); hash = cmph_new(config); cmph_config_destroy(config); char *k = (char *)malloc(sizeof(12)); while(fgets(k, INT_MAX, read) != NULL){ string key = k; unsigned int id = cmph_search(hash, k, (cmph_uint32)key.length()); ids<<id<<"\n"; } cmph_destroy(hash); cmph_io_nlfile_adapter_destroy(source); fclose(fp); fclose(read); ids.close(); } Shouldn't the ids be unique for every distinct key if the algorithm claims to generate a minimal perfect hash function? There are 2048383 keys. For my project I would need the ids to map from 0 to 2048382, since I plan to use a minimal perfect hash function. I am not sure where I am going wrong with my understanding. Please help.
If your keys2.txt contains keys that weren't part of the set that was used to generate your hash, then, by definition of the mphf, you'll get either duplicate hashes or, possibly, values out of your range. It's up to you to store all keys that were used to generate hash and then verify that the key that was passed to cmph_search was the same as the one that resulted in the hash/id returned by cmph_search
Preprocessor Quoting macro arguments
Suppose I have some macro #define NAME name, and I want to define some other macro which will expand to the quoted value. That is, as if I had also defined #define NAME_STR "name". Is there a neater way than the following? #define QUOT(str) #str #define QUOT_ARG(str) QUOT(str) #define NAME_STR QUOT_ARG(NAME)
Not really, due to the fact that macro arguments are not expanded when used in stringification. From the GNU C PreProcessor manual: Unlike normal parameter replacement, the argument is not macro-expanded first. This is called stringification. From the same source: If you want to stringify the result of expansion of a macro argument, you have to use two levels of macros. ...which continues with an example: #define xstr(s) str(s) #define str(s) #s #define foo 4 str (foo) ==> "foo" xstr (foo) ==> xstr (4) ==> str (4) ==> "4"
Problem With Macros (#define) "showing Expected identifier before numeric constant" error, in iPad
I am developing an application where i need to define several constants that will be used in more than one class.I have defined all my constants in one .h file(say "constants.h") and imported that file in myAppName_Prefix.pch file located in "Other sources" folder of the project.The classes using these constants are being compiled with out any error but other classes, where i declared some UISwipeGestureRecognizers, are throwing error as"Expected identifier before numeric constant" this is the snippet of code from one of the classes that is showing error: if (gesture.direction==UISwipeGestureRecognizerDirectionLeft) i defined my constants as: #define heading 1 #define direction 2 #define statement 3 #define refLink 4 #define correctResponse 5 #define incorrect1Response 6 if i define them in each class individually then everything as working fine. Can any one please suggest me a way how to solve this issue.
After preprocessing your code if (gesture.direction==UISwipeGestureRecognizerDirectionLeft) looks like this if (gesture. 2==UISwipeGestureRecognizerDirectionLeft) and this is obviously not valid code. The solution is to put an unique namespace string in front of your #defines. #define hariDirection 2 or #define kDirection 2 Or imho the best solution: don't use #define typedef enum { heading = 1, direction, statement, refLink, correctResponse, incorrect1Response, } MyDirection; This will do the same thing, but it won't clash with other method and variable names.
I was getting the same error message from gcc. error: expected ')' before numeric constant #define UNIQUE_NAME 0 After checking that my variable names were unique, I realised that I had a typo at the point in the code where the constant was being used. #define UNIQUE_NAME 0 //... if (test_variable UNIQUE_NAME) { //missing == //... } simple mistake, but tricky to find because gcc was pointing me towards the #define statement
Make your constants names to be unique: #define kHeading 1 #define kDirection 2 #define kStatement 3 #define kRefLink 4 #define kCorrectResponse 5 #define kIncorrect1Response 6
Macro with NSLocalizedString?
#define A #"someString" #define B NSLocalizedString(#"someLocalizableString",nil) A I'm trying to concatenate a localizable string in a "#define" but it's not work. It's that possible to do that in a Macro please?
#define A #"someString" #define B [NSLocalizedString(#"someLocalizableString",nil) stringByAppendingString:A] the result is somelocalizableStringsomeString
Variadic recursive preprocessor macros - is it possible?
I've run into a little theoretical problem. In a piece of code I'm maintaining there's a set of macros like #define MAX_OF_2(a, b) (a) > (b) ? (a) : (b) #define MAX_OF_3(a, b, c) MAX_OF_2(MAX_OF_2(a, b), c) #define MAX_OF_4(a, b, c, d) MAX_OF_2(MAX_OF_3(a, b, c), d) ...etc up to MAX_OF_8 What I'd like to do is replace them with something like this: /* Base case #1, single input */ #define MAX_OF_N(x) (x) /* Base case #2, two inputs */ #define MAX_OF_N(x, y) (x) > (y) ? (x) : (y) /* Recursive definition, arbitrary number of inputs */ #define MAX_OF_N(x, ...) MAX_OF_N(x, MAX_OF_N(__VA_ARGS__)) ...which, of course, is not valid preprocessor code. Ignoring that this particular case should probably be solved using a function rather than a preprocessor macro, is it possible to define a variadic MAX_OF_N() macro? Just for clarity, the end result should be a single macro that takes an arbitrary number of parameters and evaluates to the largest of them. I've got an odd feeling that this should be possible, but I'm not seeing how.
It's possible to write a macro that evaluates to the number of arguments it's called with. (I couldn't find a link to the place where I first saw it.) So you could write MAX_OF_N() that would work as you'd like, but you'd still need all the numbered macros up until some limit: #define MAX_OF_1(a) (a) #define MAX_OF_2(a,b) max(a, b) #define MAX_OF_3(a,...) MAX_OF_2(a,MAX_OF_2(__VA_ARGS__)) #define MAX_OF_4(a,...) MAX_OF_2(a,MAX_OF_3(__VA_ARGS__)) #define MAX_OF_5(a,...) MAX_OF_2(a,MAX_OF_4(__VA_ARGS__)) ... #define MAX_OF_64(a,...) MAX_OF_2(a,MAX_OF_63(__VA_ARGS__)) // NUM_ARGS(...) evaluates to the literal number of the passed-in arguments. #define _NUM_ARGS2(X,X64,X63,X62,X61,X60,X59,X58,X57,X56,X55,X54,X53,X52,X51,X50,X49,X48,X47,X46,X45,X44,X43,X42,X41,X40,X39,X38,X37,X36,X35,X34,X33,X32,X31,X30,X29,X28,X27,X26,X25,X24,X23,X22,X21,X20,X19,X18,X17,X16,X15,X14,X13,X12,X11,X10,X9,X8,X7,X6,X5,X4,X3,X2,X1,N,...) N #define NUM_ARGS(...) _NUM_ARGS2(0, __VA_ARGS__ ,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) #define _MAX_OF_N3(N, ...) MAX_OF_ ## N(__VA_ARGS__) #define _MAX_OF_N2(N, ...) _MAX_OF_N3(N, __VA_ARGS__) #define MAX_OF_N(...) _MAX_OF_N2(NUM_ARGS(__VA_ARGS__), __VA_ARGS__) Now MAX_OF_N(a,b,c,d,e) will evaluate to max(a, max(b, max(c, max(d, e)))). (I've tested on gcc 4.2.1.) Note that it's critical that the base case (MAX_OF_2) doesn't repeat its arguments more than once in the expansion (which is why I put max in this example). Otherwise, you'd be doubling the length of the expansion for every level, so you can imagine what will happen with 64 arguments :)
You might consider this cheating, since it is not recursive and it doesn't do the work in the preprocessor. And it uses a GCC extension. And it only works for one type. It is, however, a variadic MAX_OF_N macro: #include <iostream> #include <algorithm> #define MAX_OF_N(...) ({\ int ra[] = { __VA_ARGS__ }; \ *std::max_element(&ra[0], &ra[sizeof(ra) / sizeof(int)]); \ }) int main() { int i = 12; std::cout << MAX_OF_N(1, 3, i, 6); } Oh yes, and because of the potential variable expression in the initializer list, I don't think that an equivalent of this (using its own function to avoid std::max_element) would work in C89. But I'm not sure variadic macros are in C89 either. Here's something that I think gets around the "only one type" restriction. It's getting a bit hairy, though: #include <iostream> #include <algorithm> #define MAX_OF_N(x, ...) ({\ typeof(x) ra[] = { (x), __VA_ARGS__ }; \ *std::max_element(&ra[0], &ra[sizeof(ra)/sizeof(ra[0])]); \ }) int main() { int i = 12; std::cout << MAX_OF_N(i + 1, 1, 3, 6, i); }
No, because the preprocessor only takes one "swipe" at the file. There's no way to get it to recursively define macros. The only code that I've seen do something like this was not variadic, but used default values the user had to pass: x = MAX_OF_8 (a, b, -1, -1, -1, -1, -1, -1) assuming all values were non-negative. Inline functions should give you the same for C++ at least. As you state, it's probably better left to a function with variable arguments similar to printf().
I think that, even if you could expand macros recursively, there would be one little problem with your approach in terms of efficiency... when the macros are expanded, if the MAX_OF_[N-1] is greater, then you have to evaluate it again from scratch. Here is a silly and stupid answer that probably no one will like xD file "source.c" #include "my_macros.h" ... file "Makefile" myprogram: source.c my_macros.h gcc source.c -o myprogram my_macros.h: make_macros.py python make_macros.py > my_macros.h file "make_macros.py" def split(l): n = len(l) return l[:n/2], l[n/2:] def gen_param_seq(n): return [chr(i + ord("A")) for i in range(n)] def make_max(a, b): if len(a) == 1: parta = "("+a[0]+")" else: parta = make_max(*split(a)) if len(b) == 1: partb = "("+b[0]+")" else: partb = make_max(*split(b)) return "("+parta +">"+partb+"?"+parta+":"+partb+")" for i in range(2, 9): p = gen_param_seq(i) print "#define MAX_"+str(i)+"("+", ".join(p)+") "+make_max(*split(p)) then you'll have those pretty macros defined: #define MAX_2(A, B) ((A)>(B)?(A):(B)) #define MAX_3(A, B, C) ((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C))) #define MAX_4(A, B, C, D) (((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D))) #define MAX_5(A, B, C, D, E) (((A)>(B)?(A):(B))>((C)>((D)>(E)?(D):(E))?(C):((D)>(E)?(D):(E)))?((A)>(B)?(A):(B)):((C)>((D)>(E)?(D):(E))?(C):((D)>(E)?(D):(E)))) #define MAX_6(A, B, C, D, E, F) (((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C)))>((D)>((E)>(F)?(E):(F))?(D):((E)>(F)?(E):(F)))?((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C))):((D)>((E)>(F)?(E):(F))?(D):((E)>(F)?(E):(F)))) #define MAX_7(A, B, C, D, E, F, G) (((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C)))>(((D)>(E)?(D):(E))>((F)>(G)?(F):(G))?((D)>(E)?(D):(E)):((F)>(G)?(F):(G)))?((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C))):(((D)>(E)?(D):(E))>((F)>(G)?(F):(G))?((D)>(E)?(D):(E)):((F)>(G)?(F):(G)))) #define MAX_8(A, B, C, D, E, F, G, H) ((((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D)))>(((E)>(F)?(E):(F))>((G)>(H)?(G):(H))?((E)>(F)?(E):(F)):((G)>(H)?(G):(H)))?(((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D))):(((E)>(F)?(E):(F))>((G)>(H)?(G):(H))?((E)>(F)?(E):(F)):((G)>(H)?(G):(H)))) and the best thing about it is that... it works ^_^
If you're going down this road in C++, take a look at template metaprogramming. It's not pretty, and it may not solve your exact problem, but it will handle recursion.
First, macros don't expand recusrsively. Although, macros can have reentrance by creating a macro for each recursion level and then deducing the recursion level. However, all this repetition and deducing recursion, is taken care of by the Boost.Preprocessor library. You can therefore use the higher order fold macro to calculate the max: #define MAX_EACH(s, x, y) BOOST_PP_IF(BOOST_PP_GREATER_EQUAL(x, y), x, y) #define MAX(...) BOOST_PP_SEQ_FOLD_LEFT(MAX_EACH, 0, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) MAX(3, 6, 8) //Outputs 8 MAX(4, 5, 9, 2) //Outputs 9 Now, this will understand literal numbers between 0-256. It wont work on C++ variables or expression, because the C preprocessor doesn't understand C++. Its just pure text replacement. But C++ provides a feature called a "function" that will work on C++ expressions, and you can use it to calculate the max value. template<class T> T max(T x, T y) { return x > y ? x : y; } template<class X, class... T> auto max(X x, T ... args) -> decltype(max(x, max(args...))) { return max(x, max(args...)); } Now, the code above does require a C++11 compiler. If you are using C++03, you can create multiple overloads of the function in order to simulate variadic parameters. Furthermore, we can use the preprocessor to generate this repetitive code for us(thats what it is there for). So in C++03, you can write this: template<class T> T max(T x, T y) { return x > y ? x : y; } #define MAX_FUNCTION(z, n, data) \ template<class T> \ T max(T x, BOOST_PP_ENUM_PARAMS(n, T x)) \ { \ return max(x, max(BOOST_PP_ENUM_PARAMS(n, x)));\ } BOOST_PP_REPEAT_FROM_TO(2, 64, MAX_FUNCTION, ~)
There's a nice recursion example here The "hack" is to have a mid-step in the preprocessor to make it think that the define is not replaced by anything else at a given step.