0

How the PLUS macro work if i pass two strings to it, and it will parse them as the enum value? Thanks in advance. Sorry that i can't express myself too clearly.

#include "stdio.h"
#include <string>
#include <iostream>

using namespace std;

#define PRINT(Y) #Y
#define PLUS(X, Y) X+Y

int main( int argc, char *argv[] )
{
    typedef enum {
        FIRST,
        SECOND,
        THIRD
    };

    const char *a="THIRD", *b="SECOND";
    cout << PRINT(THIRD+SECOND is: ) << PLUS(a, b) << endl;
    return 0;
}
miniduan
  • 11
  • 3
  • 1
    You're using [reserved identifiers](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). And **never** make a non-const `char *` point to a string literal. – chris Dec 09 '13 at 05:08
  • 2
    And why do you need a macro here? Why isn't `std::cout << a` enough? – Joe Z Dec 09 '13 at 05:10
  • 2
    @JoeZ are you really complaining that he posted a short test example explaining only his problem, and not the entire code he's working on? C'mon. – Staven Dec 09 '13 at 05:11
  • 1
    I think there's some confusion what the objective is. – woolstar Dec 09 '13 at 05:12
  • 1
    @Staven: No, I'm asking what "printout the content of `char *a`" means that's different from "`cout << a`". `cout << a` prints the string pointed to by `a`, and it's already in his test. – Joe Z Dec 09 '13 at 05:13
  • I can't understand the question, are you saying that you can't compile it because of a dependency, or are you asking how it works? – qrikko Dec 09 '13 at 05:18
  • thank you chris, i added const and "str" is replaced – miniduan Dec 09 '13 at 05:20
  • jor Joe Z, that's a scenario i used, i need to pass a string to a macro, and the macro use the string plaintext as an ENUM value. – miniduan Dec 09 '13 at 05:20
  • qrikki, i am asking how it works. – miniduan Dec 09 '13 at 05:21
  • If what you want is the 2dn and 3rd couts to print the content of a, just remove the # from _TMP macro. If not, I really dont understand what you are trying to do. – yosim Dec 09 '13 at 05:28
  • @miniduan: Usually folks are trying to do the opposite: `stringify( enum_value )` so that the non-string `enum_value` becomes a quoted string. – Joe Z Dec 09 '13 at 05:30

1 Answers1

2

I think, from your followup comment, that I understand better what you're trying to do: Trying to make both a string form and non-string form of a symbol such as an enum value.

The way I usually do this is as follows:

#define Q(x) QQ(x)
#define QQ(x) #x

Then you use it with a non-string value, such as an enum:

enum { FRED = 1, BARNEY = 2 };

int main()
{
    std::cout << "The enum " << Q( FRED   ) << " has the value " << FRED   << std::endl;
    std::cout << "The enum " << Q( BARNEY ) << " has the value " << BARNEY << std::endl;
}

This prints:

The enum FRED has the value 1
The enum BARNEY has the value 2

If that's not what you're trying to accomplish, please clarify in your question and leave me a comment.

Joe Z
  • 17,413
  • 3
  • 28
  • 39
  • Hi Joe, i edited my question and made it a bit clearer. – miniduan Dec 09 '13 at 06:01
  • @miniduan: After seeing your revised question, I believe what you ask for is not possible. The compiler needs to see `enum` values as identifiers at _compile_ time. There is no way to "unstring" and get to an enum identifier hidden in a string literal. The compiler can go in the opposite direction, and put quotes around something (ie. turn `FIRST` into `"FIRST"`). If you need to look up strings and turn them into values, you can do that at _run_ time (not _compile_ time), using something like `std::map`. – Joe Z Dec 09 '13 at 13:15
  • In the context of your example, you could have written `cout << "THIRD + SECOND is " << THIRD + SECOND << endl` with no macros. What is also unclear is why you need that additional level of indirection. – Joe Z Dec 09 '13 at 13:19
  • Hi @Joe Z, thanks so much for your following up. The reason i do that is: i am in a scenario of JNI. the JNI passes a string value of the ENUM name. and my macro using the ENUM value to calculate. Currently my solution is to compare the enum names: if (str="FIRST", then use FIRST enum to logic) – miniduan Dec 10 '13 at 00:50
  • @miniduan: Ok, then what you'll need to do is look up the values in some other structure, such as `map`. The detail about JNI, and the fact that the strings are coming from outside the C++ environment is actually rather important, because you have to resolve the name at run time, not compile time. – Joe Z Dec 10 '13 at 02:16
  • yes, map the string to its int value is a good idea. Because the external string could not really be resolved by C++. Thanks a lot! – miniduan Dec 31 '15 at 07:54