Opposite of C preprocessor "stringification"
Asked Answered
E

3

49

When using C preprocessor one can stringify macro argument like this:

#define TO_STRING(x) "a string with " #x

and so when used, the result is as follows:

TO_STRING(test) will expand to: "a string with test"

Is there any way to do the opposite? Get a string literal as an input argument and produce a C identifier? For example:

TO_IDENTIFIER("some_identifier") would expand to: some_identifier

Thank you for your answers.

EDIT: For those wondering what do I need it for:

I wanted to refer to nodes in a scene graph of my 3D engine by string identifiers but at the same time avoid comparing strings in tight loops. So I figured I'll write a simple tool that will run in pre-build step of compilation and search for predefined string - for example ID("something"). Then for every such token it would calculate CRC32 of the string between the parenthesis and generate a header file with #defines containing those numerical identifiers. For example for the string "something" it would be:

#define __CRC32ID_something 0x09DA31FB

Then, generated header file would be included by each cpp file using ID(x) macros. The ID("something") would of course expand to __CRC32ID_something, so in effect what the compiler would see are simple integer identifiers instead of human friendly strings. Of course now I'll simply settle for ID(something) but I thought that using quotes would make more sense - a programmer who doesn't know how the ID macro works can think that something without quotes is a C identifier when in reality such identifier doesn't exist at all.

Electrical answered 8/8, 2011 at 12:33 Comment(6)
Out of curiosity, how would that be useful?Arose
You are either doing something for a really strange usecase or doing it completely wrong. Please describe the real problem.Beauregard
You need a C interpreter to do that :)Anisomerous
For those who wanted to know, added some explanation. :)Electrical
i've googled many times to have a solution, unfortunately, there is no solution for the moment, this option (destringify) is very useful to write a factorized c codes.Berdichev
This is why we should use PHP instead of C preprocessor. simply <? echo stripslashes($given); ?>. C preprocessor cannot be extended, whereas you can easily extend PHP preprocessor to include new preprocessing functions. C preprocessor cannot define functions, it can only define a php equivalent of a replace regex(preg_replace), except it can't even work with regex, it has to replace literals, and it can't even do that very well.).Exhilarative
N
32

No, you can't unstringify something.

Niobe answered 8/8, 2011 at 12:35 Comment(1)
More generally, the preprocessor can join tokens together, but it can't break a token apart.Construction
L
0
//unstringify test

enum fruits{apple,pear};

#define IF_WS_COMPARE_SET_ENUM(x) if(ws.compare(L#x)==0)f_ret=x;

fruits enum_from_string(wstring ws)
{
 fruits f_ret;
 IF_WS_COMPARE_SET_ENUM(apple)
 IF_WS_COMPARE_SET_ENUM(pear)
 return f_ret;
}

void main()
{
 fruits f;
 f=enum_from_string(L"apple");
 f=enum_from_string(L"pear");
}
Lindalindahl answered 24/5, 2013 at 3:16 Comment(2)
@FDinoff: Better not.Honk
this may work only if you prepare your "database" made of const strings at enum_from_string(), otherwise not :/, but interesting :)Fourier
O
-2

You can create an identifier from a string, this operation is called token-pasting in C :

#define paste(n) x##n
int main(){
    int paste(n) = 5;
    printf("%d" , x5);
}


output : 5
Overtly answered 21/10, 2022 at 20:28 Comment(1)
Token pasting does not create a token from a string (by which the OP means a string literal). Token pasting creates one token out of (generally) two tokens, provided that the result is also a valid token. A lexical merge of two tokens such as the ## operator performs does not form a valid token when one of the operand tokens is a string literal.Leschen

© 2022 - 2024 — McMap. All rights reserved.