5

Is it possible for a preprocessor macro to determine whether its argument is a string (literal) or not?

For example:

#define IS_STRING(token) ???

IS_STRING("foo")  // expands to 1
IS_STRING(foo)    // expands to 0
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
HighCommander4
  • 50,428
  • 24
  • 122
  • 194
  • What are you trying to do with this information? There might be a compile-time method in C++(11). I don't think the preprocessor has anything like that. – chris Jul 24 '12 at 03:55
  • I am trying to overload a preprocessor macro based on whether its first argument is a string or not. I just realized, though, that my approach is flawed because there is nothing preventing a user of the macro from declaring a named `const char*` and passing that instead of a string literal, in which case the wrong overload would be called... – HighCommander4 Jul 24 '12 at 04:00
  • You cannot overload macros. See answer [here](http://stackoverflow.com/a/3046932/1371116). – Isaac Jul 24 '12 at 04:03
  • @Isaac: You **can** overload macros, for some senses of "overload". For example, you can declare a variadic macro and then do different things based on the number of arguments it gets (the Boost.Preprocessor library does this). – HighCommander4 Jul 24 '12 at 04:05
  • 1
    How do you have it do something different depending on the number of args? – Isaac Jul 24 '12 at 04:11
  • @Isaac: Look at e.g. the definition of BOOST_PP_TUPLE_TO_SEQ in http://svn.boost.org/svn/boost/trunk/boost/preprocessor/tuple/to_seq.hpp – HighCommander4 Jul 24 '12 at 04:16
  • Those are different macros doing different things, not an overloaded macro... – Isaac Jul 24 '12 at 04:45
  • @Isaac: That's why I said 'for some senses of "overload"'. The effect is the same as if the macro was overloaded for 1 and 2 arguments. – HighCommander4 Jul 24 '12 at 05:02
  • 1
    It is possible for C++03, based on conversion to `char*`. If it implicitly converts to `char*` and is of type `char const[N]`, it is a string literal. However it is on the compiler level, not on the preprocessor level. – Johannes Schaub - litb Jul 24 '12 at 06:47

1 Answers1

4

Yes. But with a small difference in the output:

#define IS_STRING(token) "" token 

It will go fine for string literal. For non-strings, it will give compiler error.

Logic: Compiler concatenates string literal automatically, so "" token goes fine, if token is a string literal.

Here is a related discussion.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Is there a way that doesn't produce a compiler error for one of the cases? – HighCommander4 Jul 24 '12 at 04:02
  • @HighCommander4, no it's not possible. Even if whatever function overloads you make. The string literal will either collide with array or character string. – iammilind Jul 24 '12 at 04:05