tags:

views:

52

answers:

2
#define PLAINTEXT_TARGET "plaintext"
if( strstr(PLAINTEXT_TARGET, optarg) == PLAINTEXT_TARGET )
    /* ... */

Does the C language guarantee that PLAINTEXT_TARGET above compiles into a single instance? If the compiler may produce two instances of the macro string then the conditional above is misleading and can be false.

+5  A: 

No, it is not guaranteed by the standard. The standard says this about "string literals" (6.4.5p6):

It is unspecified whether these arrays are distinct provided their elements have the appropriate values.

These arrays refers to the array of char created from a literal string in translation phase 7.

Since you are using a macro, the code seen by the compiler is:

if( strstr("plaintext", optarg) == "plaintext" )

When optarg is "plaintext", the code reduces to

if("plaintext" == "plaintext")

As mentioned above, this is not guaranteed to be true in C.

So, you must use strcmp() instead of checking the pointers for equality, or, as in the other answer, define a char * pointer to use instead of the macro.

Alok
+6  A: 

Macros do simple textual replacement. The preprocessor replaces every occurrence of PLAINTEXT_TARGET with "plaintext", after that the compiler looks at the result and compiles that.

So the compiler sees two string literals and it's not guaranteed that those won't be stored separately (see Alok's answer for the according quote from the standard). The code is indeed misleading, it would be more reasonable to declare PLAINTEXT_TARGET as a constant:

const char* const PLAINTEXT_TARGET = "plaintext";
sth
Ahh! Your answers reference each other! I can't stop going back and forth between them!
Chris Lutz
If now only the question would have been about recursion...
sth
LOL! A good example of mutual recursion, I hope.
Alok