On Monday, July 16, 2012 3:53:13 PM UTC+1, Victor Bazarov wrote:
> On 7/15/2012 12:43 AM, Alex Vinokur wrote:
> > Different C/C++-preprocessors have diffrerent behavior on this program.
> > Is there any preprocessor standard for this case?
> There is but one Standard, ISO/IEC 14882:2011. It defines how the text
> of a C++ program is preprocessed. See subclause 2.2 and subclause 16.3.
It defines how the entire program is translated to an executable. He's
apparently using some (very common) option to dump some (not necessarily
well defined) internal state of the compiler.
> Here you have directives (#if, #else and #endif) appear inside a macro
> *invocation*. According to [cpp.replace/11], which says "If there are
> sequences of preprocessing tokens within the list of arguments that
> would otherwise act as preprocessing directives, the behavior is
> undefined", the behavior of the preprocessor is not defined by the
> Standard for your code. I think you're lucky they don't format your
> hard drive or email obscene photos to your boss on your behalf.
That's an interesting quote. I wasn't aware of this restriction. As a
programmer, of course, I'd never write code like this. I like my code
to be readable and maintainable. But I wasn't aware that it was
illegal. Thanks for pointing it out to me; I've yet another argument
against such junk.
In practice, I expect that most compilers "do the right thing" in this
case. I'm afraid that there are tons of legacy C code which counts on
it. (I can recall 8 deep nesting of #if to make a single token
conditional in some older Unix headers.)
It would be interesting if we had a valid test of something
which might be (or have been) defined by the standard.
Something along the lines of:
#include <iostream>
#define PRINT(x) std::cout << (x) << std::endl
int
main()
{
PRINT(
#if 1
"ABC"
#else
"XYZ"
#endif
);
return 0;
}
Does this compile and generate an executable? If so, what does
it output?
--
James