This question already has an answer here:
Macro expansion and stringification: How to get the macro name (not its value) stringified using another macro?
(1 answer)
Closed 8 months ago.
I am wondering if there is anyway to stringify a macro expanision that is another macro before it gets completley expanded. Easier to show in code:
#define A_MACRO 0
#define ANOTHER_MACRO A_MACRO
I want to expand ANOTHER_MACRO into the string "A_MACRO"
Double stringification does not work, it stringifies ANOTHER_MACRO into 0. I have searched and cannot find an answer and played around with macros in a test application, but I have had no luck. Is it possible?
Edit: I do not have the ability to change either macro. A_MACRO has a descriptive name that I would like to use, and we "point" to it with another macro that follows a standard name and I can grab it with a file parser. I was hoping I could just write a stringification macro to get that name, but I think I will have to find a way to latch onto it with my file parser, thanks everyone for your help.
No, there isn't. You can either not expand the macro argument, or you can fully expand it.
There may be a solution to whatever the underlying problem is, but this is a dead end.
Note that I'm trying to modify existing code, written by someone else, so answers from other similar questions most likely don't apply, as they could kick off the code with macro functions oriented coding mentality in mind, making preprocessing acrobatics much easier, which isn't the case for me.
So this is what I want to do. Let's say I have 1 function and 1 variable:
void Foo1(void);
int Foo1 = 0;
I want to turn them into:
void FOO1(void);
int FOO1 = 0;
Now as everyone knows, doing
#define Foo FOO
will not work as the C preprocessor will not treat Foo out of Foo1 as a single token but rather, it will treat Foo1, the whole of it, as a token.
So I need to somehow "trick" the C preprocessor into believing Foo is a token, then work on it.
I tried this:
#define a_random_thing Foo
#define Foo FOO
naively believing preprocessor will consider "Foo" a product of "a_random_thing" after expansion, and then perform another round of expansion on "Foo".
That sadly and obviously didn't work.
So what exactly should I do?
The code I'm working on is an updated library, and tons of the variable names and function names were modified ever so slightly — just enough to gave me 100+ compilation errors; very thoughtful on their part. I'm trying to make it backward compatible.
If what I'm trying to accomplish is not possible, please also tell me, thanks!
It's not really possible unless you go ahead and define foo1, foo2, foo3...
You simply can't split foo1 into two different pre-processor tokens, which would be required in order to solve the problem variably.
The closest thing you can do is #define foo(n) FOO##n and call it as foo(1) to get FOO1.
...or you could probably just do search & replace in a text editor.
The reason this won't work is because tokenization happens in the lexing phase of the compilation process. In this phase, the C compiler will parse the sequence of bytes as per C's lexical rules to create tokens (individual elements of the code: keywords, names for variables and functions, operations like +-*/, etc.).
The lexing phase works before the C pre-processor. At this time, the pre-processor looks for tokens matching the macro definition, and replaces them. Already, what your program will have are tokens called foo1, and a macro defining FOO.
I would suggest you look at string replacement tools sed/awk to solve your problem.
Could I implement this in C?
#define X abc
then X_menu(); will be preprocessed as abc_menu();
In another build
if I define X def
then X_menu(); will be def_menu();
I'm sure there should be a method, but I could not figure out.
No, you wouldn't want this behavior as it would be very unsafe and difficult to deal with replacing every X in every name. However, you could use a macro function to do something similar
#define X(F) abc##F
X(_menu();)
## is macro concatenation, so X(_menu();) will expand to abc_menu();
As Roger points out, the macro will also work with the syntax
X(_menu)();
which you may find easier to read
I want to fill a multidimensional array using a macro so that the people using it think that they are using a function and passing only one string. The macro will use this string and at compile time convert it so that it would appear as a multidimensional array, like this:
make_array ("string1,{string2,{string3,{...,{stringN");
So the macro will replace this function to a multidimensional array and cut that string wherever it encounters,{. The code above will turn in something like this:
make_array = { "string1", "string2", "string3", ..., "stringN"};
I'm using GCC; how can I accomplish this?
Update: I thought I could exclude the quotes of the string using a macro, so I would have a string without a text and I could edit the string in macro but GCC does not accept the declaration of a macro to replace double quotes (like shown below).
#define macro_array ( "text") text
So the text will appear without double quotes and I could find the ,{ mark and cut it and use then stringify to turn the string back.
You can get a moderate approximation to what you are after with C99 and variable arguments in macros:
Source
#define make_array(name, dim1, dim2, ...) \
static char name[dim1][dim2] = { __VA_ARGS__ }
make_array(mine, 2, 2, "abc", "def", "ghi", "jkl");
Output
$: gcc -E xx.c
# 1 "xx.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "xx.c"
static char mine[2][2] = { "abc", "def", "ghi", "jkl" };
$
However, you cannot readily split a string in the preprocessor as requested - it is simply the wrong tool for the job.
You cannot do string processing with macros.
I'm not sure I understand exactly what you want to do, but this is probably best achieved with a function.
Forget it. I see way too many questions along the lines of "How can I make my code look like this?" when the question for achieving good code should be "How can I make my code work like this?" What is the goal you're trying to achieve?
If you want to import external data that was formatted in the weird notation you specified, does the data vary at runtime or is it constant? In the former case you'll need a parser in your program and a good deal of dynamic allocation. In the latter case, you need to write a program that runs before compiling the main program which parses and converts the data into C. But if there's no legitimate reason for the data to be in this weird format to begin with, you should simply write it in C from the start rather than trying to force C to look like something else.
Get rid of the quotes and use a variadic macro
Write a function to split the string and call it from the macro
Don't use macros for this, just make a static inline function. It is just as fast.
As Oli has already said, this kind of string processing is impossible with macros. Concatenation and replacement of other strings is about as much as you can do with macros.
I think the answer here is a question- why does the input string have to be of that format? Writing your required result does not require any more effort than it is to write your input, so why would you want to go through the pain of processing it?
I was asked a question in C last night and I did not know the answer since I have not used C much since college so I thought maybe I could find the answer here instead of just forgetting about it.
If a person has a define such as:
#define count 1
Can that person find the variable name count using the 1 that is inside it?
I did not think so since I thought the count would point to the 1 but do not see how the 1 could point back to count.
Building on #Cade Roux's answer, if you use a preprocessor #define to associate a value with a symbol, the code won't have any reference to the symbol once the preprocessor has run:
#define COUNT (1)
...
int myVar = COUNT;
...
After the preprocessor runs:
...
int myVar = (1);
...
So as others have noted, this basically means "no", for the above reason.
The simple answer is no they can't. #Defines like that are dealt with by the preprocessor, and they only point in one direction. Of course the other problem is that even the compiler wouldn't know - as a "1" could point to anything - multiple variables can have the same value at the same time.
Can that person find the variable name "count" using the 1 that is inside it?
No
As I'm sure someone more eloquent and versed than me will point out #define'd things aren't compiled into the source, what you have is a pre-processor macro which will go through the source and change all instance of 'count' it finds with a '1'.
However, to shed more light on the question you were asked, because C is a compiled language down to the machine code you are never going to have the reflection and introspection you have with a language like Java, or C#. All the naming is lost after compilation unless you have a framework built around your source/compiler to do some nifty stuff.
Hope this helps. (excuse the pun)
Unfortunately this is not possible.
#define statements are instructions for the preprocessor, all instances of count are replaced with 1. At runtime there is no memory location associated with count, so the effort is obviously futile.
Even if you're using variables, after compilation there will be no remnants of the original identifiers used in the program. This is generally only possible in dynamic languages.
One trick used in C is using the # syntax in macros to obtain the string literal of the of the macro parameter.
#define displayInt(val) printf("%s: %d\n",#val,val)
#define displayFloat(val) printf("%s: %d\n",#val,val)
#define displayString(val) printf("%s: %s\n",#val,val)
int main(){
int foo=123;
float bar=456.789;
char thud[]="this is a string";
displayInt(foo);
displayFloat(bar);
displayString(thud);
return 0;
}
The output should look something like the following:
foo: 123
bar: 456.789
thud: this is a string
#define count 1 is a very bad idea, because it prevents you from naming any variables or structure fields count.
For example:
void copyString(char* dst, const char* src, size_t count) {
...
}
Your count macro will cause the variable name to be replaced with 1, preventing this function from compiling:
void copyString(char* dst, const char* src, size_t 1) {
...
}
C defines are a pre-processor directive, not a variable. The pre-processor will go through your C file and replace where you write count with what you've defined it as, before compiling. Look at the obfuscated C contest entries for some particularly enlightened uses of this and other pre-processor directives.
The point is that there is no 'count' to point at a '1' value. It just a simple/find replace operation that happens before the code is even really compiled.
I'll leave this editable for someone who actually really knows C to correct.
count isn't a variable. It has no storage allocated to it and no entry in the symbol table. It's a macro that gets replaced by the preprocessor before passing the source code to the compiler.
On the off chance that you aren't asking quite the right question, there is a way to get the name using macros:
#define SHOW(sym) (printf(#sym " = %d\n", sym))
#define count 1
SHOW(count); // prints "count = 1"
The # operator converts a macro argument to a string literal.
#define is a pre-processor directive, as such it is not a "variable"
What you have there is actually not a variable, it is a preprocessor directive. When you compile the code the preprocessor will go through and replace all instaces of the word 'count' in that file with 1.
You might be asking if I know 1 can I find that count points to it? No. Because the relationship between variables names and values is not a bijection there is no way back. Consider
int count = 1;
int count2 = 1;
perfectly legal but what should 1 resolve to?
In general, no.
Firstly, a #define is not a variable, it is a compiler preprocessor macro.
By the time the main phase of the compiler gets to work, the name has been replaced with the value, and the name "count" will not exist anywhere in the code that is compiled.
For variables, it is not possible to find out variable names in C code at runtime. That information is not kept. Unlike languages like Java or C#, C does not keep much metadata at all, in compiles down to assembly language.
Directive starting with "#" are handled by the pre-processor which usually does text substitution before passing the code to the 'real' compiler. As such, there is no variable called count, it's as if all "count" strings in your code are magically replaced with the "1" string.
So, no, no way to find that "variable".
In case of a macro this is preprocessed and the resulting output is compiled. So it is absolutely no way to find out that name because after the preprocessor finnishes his job the resulting file would contain '1' instead of 'count' everywhere in the file.
So the answer is no.
If they are looking at the C source code (which they will be in a debugger), then they will see something like
int i = count;
at that point, they can search back and find the line
#define count 1
If, however, all they have is variable iDontKnowWhat, and they can see it contans 1, there is no way to track that back to 'count'.
Why? Because the #define is evaluated at preprocessor time, which happens even before compilation (though for almost everyone, it can be viewed as the first stage of compilation). Consequently the source code is the only thing that has any information about 'count', like knowing that it ever existed. By the time the compiler gets a look in, every reference to 'count' has been replaced by the number '1'.
It's not a pointer, it's just a string/token substitution. The preprocessor replaces all the #defines before your code ever compiles. Most compilers include a -E or similar argument to emit precompiled code, so you can see what the code looks like after all the #directives are processed.
More directly to your question, there's no way to tell that a token is being replaced in code. Your code can't even tell the difference between (count == 1) and (1 == 1).
If you really want to do that, it might be possible using source file text analysis, say using a diff tool.
What do you mean by "finding"?
The line
#define count 1
defines a symbol "count" that has value 1.
The first step of the compilation process (called preprocessing) will replace every occurence of the symbol count with 1 so that if you have:
if (x > count) ...
it will be replaced by:
if (x > 1) ...
If you get this, you may see why "finding count" is meaningless.
The person asking the question (was it an interview question?) may have been trying to get you to differentiate between using #define constants versus enums. For example:
#define ZERO 0
#define ONE 1
#define TWO 2
vs
enum {
ZERO,
ONE,
TWO
};
Given the code:
x = TWO;
If you use enumerations instead of the #defines, some debuggers will be able to show you the symbolic form of the value, TWO, instead of just the numeric value of 2.