I was wondering is there can be a way to stringize an integer variable using stringizing compiler directive.
I tried using:
#define stringize(a) #a
#define h(a) stringize(a)
#define g(a,b) a##b
#define f(a,b) g(a,b)
int main()
{
int num = 1024;
printf("%s=%s\n",stringize(h(f(1,2))), h(f(1,2))); //1. h(f(1,2))=12
printf("%s=%s\n",h(h(f(1,2))), h(f(1,2))); //2. "12"=12
printf("%s=%d\n", h(num),num); //num=1024
return 0;
}
so as adding another level in stringize macro(#1) will make the substitution to happen first then placing it in code(#2), in similar way can variables be replaced at compile time with the values.
I mean to say if var = value; then is there some way that
some_macro(var) --> can stringize it into "value"?
There's no way of getting the value of a variable using the preprocessor - preprocessing (as its name suggests) takes place before compilation, and the variables do not exist at that stage.
No. The preprocessor is acting on tokens, it doesn't know about variables and their values. What would you want to get if the value was read from stdin?
Related
I have read lots on stringizing macros, but I obviously don't quite understand. I wish to make a string where the argument to the macro needs to be evaluated first. Can someone please explain where I am going wrong, or perhaps how to do this better?
#define SDDISK 2 // Note defined in a library file elsewhere ie not a constant I know)
#define DRIVE_STR(d) #d ":/"
#define xDRIVE_STR(x) DRIVE_STR(x)
#define FILEPATH(f) xDRIVE_STR(SDDISK + '0') #f
const char file[] = FILEPATH(test.log);
void main(void)
{
DebugPrint(file);
}
The output is: "2 + '0':/test.log",
But I want "2:/test.log"
The C PREprocessor runs before the compiler ever sees the code.
This means that the equation will not be evaluated before it is stringified; instead, the preprocessor will just stringize the whole equation.
In your case just removing the +'0' will solve the problem as the value of SDDISK does not need casting to a char before it is stringified.
However, should you actually need to perform a calculation before stringizing you should either:
Use cpp's constexpr.
Complain to your compiler vendor that a constant expression was not optimized.
Use a preprocessor library to gain the wanted behaviour.
So when looking into getting my define macro to work, I found the # and ## macro helpers, and used them to simplify my macro. The key part of the macro sets a variable to a string containing the name of the variable (but not the variable name alone). As a simplified example, let's take a macro called SET(X) that should expand SET(something) into something = "pre_something".
The only way I've found to do it so far is with two macros like #define QUOTE(X) #X and #define SET(X) X = QUOTE(pre_##X). However, using multiple macros seems excessive, and may cause problems with further macro expansion (I think). Is there a cleaner, one-line way of doing the same thing?
#define SET(x) x = "pre_"#x
C does string concatenation at compile time, so two string literals next to each other are concatenated.
"hello " "world" -> "hello world"
Let's say I have already defined 9 macros from
ABC_1 to ABC_9
If there is another macro XYZ(num) whose objective is to call one of the ABC_{i} based on the value of num, what is a good way to do this? i.e. XYZ(num) should call/return ABC_num.
This is what the concatenation operator ## is for:
#define XYZ(num) ABC_ ## num
Arguments to macros that use concatenation (and are used with the operator) are evaluated differently, however (they aren't evaluated before being used with ##, to allow name-pasting, only in the rescan pass), so if the number is stored in a second macro (or the result of any kind of expansion, rather than a plain literal) you'll need another layer of evaluation:
#define XYZ(num) XYZ_(num)
#define XYZ_(num) ABC_ ## num
In the comments you say that num should be a variable, not a constant. The preprocessor builds compile-time expressions, not dynamic ones, so a macro isn't really going to be very useful here.
If you really wanted XYZ to have a macro definition, you could use something like this:
#define XYZ(num) ((int[]){ \
0, ABC_1, ABC_2, ABC_3, ABC_4, ABC_5, ABC_6, ABC_7, ABC_8, ABC_9 \
}[num])
Assuming ABC_{i} are defined as int values (at any rate they must all be the same type - this applies to any method of dynamically selecting one of them), this selects one with a dynamic num by building a temporary array and selecting from it.
This has no obvious advantages over a completely non-macro solution, though. (Even if you wanted to use macro metaprogramming to generate the list of names, you could still do that in a function or array definition.)
Yes, that's possible, using concatenation. For example:
#define FOO(x, y) BAR ##x(y)
#define BAR1(y) "hello " #y
#define BAR2(y) int y()
#define BAR3(y) return y
FOO(2, main)
{
puts(FOO(1, world));
FOO(3, 0);
}
This becomes:
int main()
{
puts("hello " "world");
return 0;
}
I'm working in a C program and I came across a problem. I have this
#define NUMBER_OF_OPTIONS 5
#define NAME_OPTION1 "Partida Rapida"
#define NAME_OPTION2 "Elige Nivel"
#define NAME_OPTION3 "Ranking"
#define NAME_OPTION4 "Creditos"
#define NAME_OPTION5 "Exit"
for (iterator = 1; iterator <= NUMBER_OF_OPTIONS; iterator++){
menu_options[iterator-1]= NAME_OPTION + iterator
}
I want that "NAME_OPTION + iterator" takes the value of the corresponding #define. For example if the variable "iterator" is equal to one, I want menu_options[iterator-1] to take the value of NAME_OPTION1, which is "Partida Rapida".
How can I get this?
Essentially, you can't. #define macros are handled by the C Preprocessor and do textual substitution wherever that macro appears in the code. The macro NAME_OPTION has not been defined, so the compiler should complain. C does not allow appending numbers onto strings, or especially onto symbols like NAME_OPTION. Use an array of const char*, which you can then refer to with your iterator.
You can't use defines as this, you can do:
const char *menu_options[5] = {
"Partida Rapida",
"Elige Nivel",
"Ranking",
"Creditos",
"Exit"
};
If you use #define macro, you just tell preprocessor to replace every occurence of defined word by something else before the code is compiled into machine code.
In this case NUMBER_OF_OPTIONS will be replaced by 5, but there's no occurence of NAME_OPTION*, so nothing will be replaced and you'll probably get an error while preprocessing.
Piere's solutions shows how to do it, but I highly doubt that there's an iterator over char *array, so you have to iterate over given array using an integer index.
I'm trying to do something like:
#define __attribute__((aligned(2))) __attribute__((space(prog),aligned(2)))
but the compiler yields :
error: "(" may not appear in macro parameter list
Questions: What gives? How can I do a literal text replace, no bells, no frills ?
As soon as you start with a parenthesis, you're defining a macro with arguments, and that's bound to some rules.
So you can do, for example:
#define succ(x) (x + 1)
But you can't do:
#define pred(x + 1) x
The preprocessor only does a very limited set of pattern matching.
What you could do instead is something like:
#define __aligned2__ __attribute__((space(prog),aligned(2)))
And use that define instead. If that's not sufficient for your needs, you'll need to do some custom preprocessing using sed instead.
This is not possible with the C preprocessor. You can only define "literal txt replace"s, as you put it, if the text you want to replace is a single identifier ("object-like macro" in C standard parlance). What you wrote causes the preprocessor to think you're trying to define a "function-like macro", with a parameter named "(aligned(2))", which is a syntax error.
I would deal with this problem by wrapping the entire __attribute__ construct in an object-like macro:
#if appropriate condition
#define ATTRIBUTE_ALIGNED_2 __attribute__((space(prog),aligned(2)))
#else
#define ATTRIBUTE_ALIGNED_2 __attribute__((aligned(2)))
#endif
and then replacing __attribute__((aligned(2))) with ATTRIBUTE_ALIGNED_2 throughout the source code.