What is the expected output when redefining true to false and vice versa?

佐手、 提交于 2019-12-23 07:46:39

问题


#include <iostream>
#define true false
#define false true
int main() {
    std::cout << false << true;
}

Why does it output "01"?


回答1:


As Jerry Coffin notes, you cannot define a macro with a name that is a keyword.

However, we could consider another, similar example, with well-defined behavior and the same result. Consider:

int TRUE = 1;
int FALSE = 0;

#define TRUE FALSE
#define FALSE TRUE

std::cout << FALSE << TRUE;

When you use FALSE, it is identified as the macro FALSE and is replaced by that macro's replacement list, which is the single token, TRUE. That replacement is then rescanned for further macros to replace.

The TRUE in the replacement is then identified as a macro and is replaced by its replacement list, which is the single token FALSE. That replacement is again rescanned.

If we continued on rescanning and replacing, we'd end up in an infinite loop, so the C (and C++) preprocessing specifications state that macro replacement never recurses within a replacement list.

Since replacement of FALSE in this final replacement list would result in recursion, macro replacement stops and we are left with FALSE, which is the name of an int with a value of 0.




回答2:


Any attempt at re-defining a reserved word gives undefined behavior.

Edit:

§2.11/1: "The identifiers shown in Table 3 are reserved for use as keywords." I won't try to reproduce all of Table 3, but it includes both false and true. It may be open to some question whether this is an absolute prohibition, though, since the same sentence adds: "(that is, they are unconditionally treated as keywords in phase 7)", which suggests that it's possible to re-define keywords this way, since the macros involved would be/are expanded before phase 7.

In this case, however, you've also included <iostream>, which brings another rule into play (§17.4.3.1.1): "A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords."

The wording here strongly suggests that there's an intent that if a translation unit didn't include any header, it would be free to re-define a keyword as you've done, but given the presence of the #include <iostream>, there's no question that you have undefined behavior.

Once you have undefined behavior, there really is no more to say about "why" anything happens -- at that point, the standard is very clear that any behavior is permissible.



来源:https://stackoverflow.com/questions/9523025/what-is-the-expected-output-when-redefining-true-to-false-and-vice-versa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!