或者不是有效的C++:为什么这段代码会编译?

24

这是我用QtCreator制作的非常简单的C++应用程序:

int main(int argc, char *argv[])
{
    int a = 1;
    int b = 2;

    if (a < 1 or b > 3)
    {
       return 1;
    }
    return 0;
}

对我来说,这并不是有效的C++代码,因为关键字or不是一个保留关键字。

但是,如果我编译并运行它,它可以正常工作,没有任何警告!退出代码为0,如果我改变b = 4,退出代码为1!

我没有包含任何内容来确保没有隐藏的定义。

这对我来说真的很奇怪。这是Qt正在定义的吗?我在文档中没有找到任何相关内容。


15
"well spotted" 是什么意思?又或者说,is 在 C++ 中是一个关键字。 - Michael Foukarakis
@MichaelFoukarakis 我认为“well spotted”是指问题中的“为什么这段代码能编译?”:一些编译器需要 #include <iso646.h> ,而有些则不需要。大多数(如果不是全部)集成开发环境不会突出显示这些新的“关键字”。 - Wolf
3个回答

56
根据维基百科
C++定义关键字作为符号的别名,这些符号作为运算符:and(&&),bitand(&),and_eq(&=),or(||),bitor(|),or_eq(|=),xor(^),xor_eq(^=),not(!),not_eq(!=),compl(~)。
MadKeithV指出,这些替换来自于C的iso646.h,并被包含在ISO C++中作为运算符关键字。 iso646.h的维基百科文章称,这些关键字的原因确实是为了国际和其他可能没有易于访问符号的非QWERTY键盘。

2
厉害了 - 自从90年代初就开始写C++,竟然对这个一无所知。虽然我可能永远不会“用”上它,但知道这个还是挺好的。 - Graeme Perrow
我之前也不知道,直到我查看了相关资料。它的使用似乎有些棘手,我相信有很多写C++的人并不知道它的存在。 - Thomas Owens
1
我相信这些是为了帮助使用非英语键盘的人们,因为他们可能没有所有的符号键(&,|等)。 - KeithB
3
+1. 有些人在IRC上做了这个:struct y { compl y(); }; :) - Johannes Schaub - litb
3
最近我开始在一些地方使用<ciso646>(在C++程序中包含iso646.h的正确方式),特别是在单元测试中。例如:if (!someCondition) 看起来不太好懂,但是 if (not someCondition) 对我来说更易读,因为有时会在括号旁边忽略掉 ! 符号。 - Patrick Johnmeyer
如果你的编译器不符合标准,那么就需要它,而多年来许多编译器都不符合标准。 :) 我不记得我在 09 年用的是什么编译器,但我确实需要这个包含文件。话虽如此,回想起来,我不确定是否会推荐这种做法给其他人,特别是考虑到备选形式的名称不一致。 - Patrick Johnmeyer

16
< p > < code > or 是C++的一个关键字,可以用它代替 < code > || 。没有魔法。

对于and和大多数其他逻辑运算符也是如此。但最好坚持使用广为人知的名称,以避免产生混淆。如果你使用or,有人会想知道“为什么这个可以编译”;)


旧答案,我知道,但我只是想很酷地挑剔并指出它们不是关键字,而是替代标记。我感觉自己很酷,很讨厌。 </sarcasm> - GManNickG
哦,对了,我没有意识到这个区别。但是,看起来你是正确的。 :) - jalf
@GManNickG:它们是关键字(至少在当前工作草案中):第C.5.2.3节:“这个国际标准(2.11)中的tokens、and、and_eq、bitand、bitor、compl、not_eq、not、or、or_eq、xor、and xor_eq是关键字。它们不会出现在<ciso646>中定义的宏名称中。” - Hannes

7

iso646.h定义了许多运算符的替代形式,它是C++标准的一部分。


在C++中,<iso646.h>是空的。 - avakar
2
它不在Visual Studio 2003到2010中(http://msdn.microsoft.com/en-us/library/bw6140c5%28VS.80%29.aspx) - Joris Timmermans
让我重新表述一下:就C++编译器而言,该文件是空的。检查源代码,你会发现宏是有条件的,取决于__cplusplus宏是否被定义。 - avakar
除非定义了_MSC_EXTENSIONS - Joris Timmermans
MSVC自1989年C标准以来添加的许多内容都没有实现。 <iso646.h>是作为1994年更改的一部分添加的,还有各种宽字符头文件等。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接