Editing/Redefining a Macro Constant String:

Started by
3 comments, last by King Mir 11 years, 2 months ago

Hello

I am attempting to change a constant variables value, *yes I am aware of the contradiction of what I am doing* but there is a method to my maddness.

You see I am writting in a language very similar to C/C++ called 4dm but it doesn't allow any code outside of functions so I am trying to overcome this by using pre-processor commands. The reason is so I can achieve a form of specialisation in the language. The first step of this involves being able to edit a constant string.

Even though this is a different language, the preprocessor operates in exactly the same way as C and C++ compilers:


#define MY_STR "abc"
    #define CONCAT(s) \
        #define TEMP MY_STR \  // store MY_STR in TEMP_STR
        #undef MY_STR \        // undefine MY_STR
        #define MY_STR TEMP s  // redefine MY_STR so it contains the old value plus the new one
        
    CONCAT(def)
    printf("%s\n", MY_STR);  // should hopefully print out "abc def"
 


The following is a simple attempt at concatenating a string but I get a compile error saying `MY_STR is not defined` any ideas how to fix this?


#define MY_STR abc
    #define TEMP MY_STR
    #undef MY_STR
    #define MY_STR TEMP def

    void test()
    {
        print(MY_STR);
    }
 

Advertisement

You can probably do what you are attempting to do with the preprocessor operator ##, which concatenates two strings.

Thanks I didn't know about that operator. I'll give it a go


#define MY_STR "abc"
    #define CONCAT(s) \
        #define TEMP MY_STR \  // store MY_STR in TEMP_STR
        #undef MY_STR \        // undefine MY_STR
        #define MY_STR TEMP s  // redefine MY_STR so it contains the old value plus the new one
        
    CONCAT(def)
    printf("%s\n", MY_STR);  // should hopefully print out "abc def"

This will NOT work in C/C++. The preprocessor will evaluate the body of the macro once it is invoked for replacement, and no sooner. You also can't put preprocessor directives that alter the definitions of macros inside of a macro body in Standard C/C++. That means that first you define MY_STR to the sequence of tokens "abc", and you define CONCAT(s) to the sequence of tokens #define TEMP MY_STR #undef MY_STR #define MY_STR TEMP s. Even if you could, you would literally #define TEMP to the sequence of tokens MY_STR.

When you go to invoke TEMP, it then replaces it with MY_STR. When that is invoked, it is replaced with "abc". Next, you undefine MY_STR. The next time TEMP is used, the macro substitution stops there, because it is no longer a macro, and just leaves MY_STR, which causes an error when compiled. And lastly, #define MY_STR TEMP s will re-#define MY_STR to the sequence of tokens TEMP (tokens represented by s). As we saw just a moment ago, TEMP is defined to contain the token MY_STR, not its value, so MY_STR is #define'd to MY_STR (tokens represented by s). And this will throw an error if it didn't halt the compilation already.

The preprocessor does not copy values of macros! It just adds the macro's name to the list of tokens that the macro represents, and it will expand and replace it when it is used.

For C: (§6.10.3.4/3: "The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one ...").

For C++: (§16.4.3/3: "The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one...").

You can probably do what you are attempting to do with the preprocessor operator ##, which concatenates two strings.

That's not what ## does. ## concatenates two tokens. String literals do not need a special directive to concatenate; two sting literals written one after another will concatenate.

This topic is closed to new replies.

Advertisement