• FEATURED

View more

View more

View more

\$10

Image of the Day Submit

IOTD | Top Screenshots

Editing/Redefining a Macro Constant String:

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

4 replies to this topic

#1gretty  Members

Posted 10 February 2013 - 11:13 PM

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);
}


#2frob  Moderators

Posted 11 February 2013 - 01:22 AM

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

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I occasionally write about assorted stuff.

#3gretty  Members

Posted 11 February 2013 - 01:34 AM

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

#4Ectara  Members

Posted 11 February 2013 - 09:37 AM

#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...").

Edited by Ectara, 11 February 2013 - 09:58 AM.

#5King Mir  Members

Posted 11 February 2013 - 10:49 AM

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.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.