48

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.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
MasterM
  • 1,173
  • 1
  • 9
  • 15
  • 4
    Out of curiosity, how would that be useful? – Kerrek SB Aug 08 '11 at 12:35
  • 6
    You are either doing something for a really strange usecase or doing it completely wrong. Please describe the real problem. – the_drow Aug 08 '11 at 12:37
  • You need a C interpreter to do that :) – useraged Aug 08 '11 at 12:43
  • 2
    For those who wanted to know, added some explanation. :) – MasterM Aug 08 '11 at 20:53
  • 1
    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. – elhadi dp ıpɐɥןǝ Mar 14 '13 at 09:25
  • 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.). – Dmytro Oct 14 '16 at 02:11

3 Answers3

31

No, you can't unstringify something.

Puppy
  • 144,682
  • 38
  • 256
  • 465
1
//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");
}
-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
James Risner
  • 5,451
  • 11
  • 25
  • 47
  • 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. – John Bollinger Oct 27 '22 at 13:09