“not, and, or, not_eq…”是否是C++标准的一部分?(以及它们在代码中为什么会被使用或避免?)

7

看起来这些东西: http://www.cplusplus.com/reference/clibrary/ciso646/ 都是C++中的关键字。

我的问题是,这是C++标准的一部分吗?

我能否依赖主要编译器支持它们?我知道gcc确实支持这些关键字。

最后,也许这更多是个偏好或风格的问题,但使用这些关键字是否有什么优势,与使用标准运算符(!、!=、&&等)相比呢?


1
有什么优点吗?其实并没有。我会质疑使用它们的代码。 - Cat Plus Plus
2
@CatPlusPlus 我可以理解有时候在条件语句中使用 not,因为它比 ! 更不容易被忽视。 - Daniel Fischer
1
@CatPlusPlus,欢迎对我的代码提出任何问题。我们要把这个问题带到聊天室吗?你选择什么武器? - Konrad Rudolph
@KonradRudolph:香蕉。 - Cat Plus Plus
我对这些运算符的“抱怨”是没有相应的eq/is_eq(我很乐意放弃我避免的位运算形式):| - user2864740
5个回答

11
我的问题是,这是C++标准的一部分吗?
是的。
我可以依赖主要编译器支持它吗?
是的。但是 MSVC 默认情况下不支持此选项,您需要传递选项/permissive-(或者,虽然已过时和有缺陷,/Za),以禁用 Microsoft 语言扩展。 对于几乎所有C ++项目启用此选项似乎是个好主意,只是很遗憾默认情况下它被关闭。
但是使用这些关键字是否有优势而不是使用标准运算符呢?
总体来说,没有。但对于andornot等情况,许多人(尽管可能不是大多数人)认为它更易读。个人建议使用它们。
如果您绝对希望在不使用 /permissive- 标志的情况下编译MSVC代码,那么请添加#include <ciso646>(这是一个标准头文件,在符合C ++实现的情况下为空,但会为MSVC添加运算符宏)。

在gcc中,关键字只是宏展开为运算符吗? - anio
4
对谁来说更易读呢?大多数有经验的C系编程人员在看到包含这些运算符而不是他们习惯使用的&&||!时会感到困惑。我认为对于编程人员来说这种写法反而易读,而编程人员正是你在考虑编写“易读”代码时应该针对的对象。 - user229044
3
大多数编程语言都使用逻辑表达式的关键字,要么是专门的关键字,要么是可以作为可选项的关键字。就我所知,C#和Java是唯一不允许这样做的语言(但我敢打赌还有其他更多的语言)。C程序员可能不习惯这种写法,但同样的理由也可以用来禁止其他好的特性,并且这个理由对我没有任何影响。其中,not x! x更易读,因为它使运算符更加明显,不太可能被忽略。而且,我认为a and b很清楚地表明我们正在处理逻辑条件,而不是数字。 - Konrad Rudolph
2
我并不是在争论其他特性,我在争论的是对于一个有经验的程序员来说,“&&”比“and”更易读。这是一个熟悉C风格语言的人在if语句中将两个变量粘合在一起时所期望看到的。 - user229044
可读性取决于上下文。尤其是感叹号!往往容易被忽视。只需考虑return !someThing.isValid();return not someThing.isValid();的区别。 - Ichthyo
显示剩余2条评论

7

这是C++标准的一部分吗?

是的。请参见[lex.digraph]部分的表格。

使用关键字是否有任何优势?

我的理解是原始的双字符替换(<%代替{等)是为了让使用简单键盘的人能够编写C代码(维基百科支持此说法)。也许相同的理由适用于not_eq等。但据我所知,现在没有什么好理由去编写这样的代码(除非你在手机上编程),尤其是因为99%的程序员不知道它是有效的C++代码!


5

是的,它们得到支持。

就你问题的后半部分而言,它们可以导致更易读的代码,特别是在处理位运算符以及同时处理逻辑操作时,例如:

if( a & 1 == 0 || c | a == 2 );

vs

if( a & 1 == 0 or c | a == 2 );

1
我不同意关于位运算符的观点。bit_and并不比&更易读,就像a plus b不如a + b易读一样。但我同意它可以使逻辑表达式更易读。 - Konrad Rudolph
1
哦,我没有说清楚,我是指逻辑运算与位运算混合在一起的情况。 - sean
为了可读性,我不会混合使用不同类型的运算符。坚持使用一种类型的运算符,你的代码维护者就不必在每次运算符改变时进行心理上的切换。 - user229044
1
@meagar 什么心理上的上下文切换?! 混合操作员是一件事。其他语言似乎没有考虑到存在有害上下文切换这一点。 - Konrad Rudolph
1
@Konrad 或许我的思维已经受到了偏见,因为我过去一年主要在 Ruby 中工作,那里的 and&& 不是同一回事。然而,我仍然认为,在代码行中,运算符作为标点符号突出显示,变量作为单词突出显示会更容易阅读,如果一行代码混合使用普遍存在的 && 风格运算符和不太常用的 and 风格运算符,我会感到非常分心。 - user229044

4
它们在标准中,但支持有些不太均衡。经验丰富的程序员发现它们比通常的符号(||&&!=等)更难读懂,因此除非你只想对不支持它们的编译器厂商做出政治声明,否则最好避免使用它们。
至少在我看来,它们的定义也相当糟糕。特别是,它们是按令牌而非逻辑定义的。一般情况下(三字符组,双字符组和这些东西)实际原因是为了允许在不支持语言使用的特殊字符的古老终端上使用语言。这些替代令牌被添加以使其略微不那么令人讨厌的三字符组和双字符组。我想他们在这方面取得了成功,但仍然只是略微令人讨厌,而不是任何应该被选择使用的东西。
让我们考虑一些例子。如果您诚实地处于那些古老的终端之一,并且您想编写通过引用传递参数的代码,该怎么做?
void foo(T bitand param);

从这里可以明显看出如何通过右值引用传递一个值:

void foo(T and param);

虽然看起来有点傻丑,但至少解决了关于 T& paramT &param 的争议——使用 bitand 时需要在两侧都留出空格。但是,这样做会让人误解、困惑和难以阅读。

哦,还要小心不要将其拼写为 bit_and 而不是 bitand。还有一个名为 bit_and 的东西,但它完全不同——bitand 是一个预处理器标记,而 bit_and 是在 <functional> 中定义的函数模板。使用错误的标记可能会导致一些令人困惑的编译器错误。

尽管如此,我可以想到一种情况,其中 andbitand 等可能是合理的。如果(出于某种原因)您无法键入代码,并且必须使用语音识别软件,则使用基于单词的标记可能会更容易,例如输入 and 要比输入 && 更容易。虽然辨别 bitandbit_and 可能更加困难,但后者很少使用,所以可能不是什么大问题。

总结

对于一些人来说,使用接受的符号输入代码确实很困难,因此使用基于单词的标记是合理的。

对于其他任何人,即使他们个人认为 and&& 更易读,在别人面前使用这样的代码也像我在五岁时决定将加法函数命名为 biggerate 一样可笑。因此,如果您喜欢它们,并且您编写的代码绝对、肯定不会被其他人阅读,请放心使用。否则,使用它们是一个不好的想法。


5
这是一个过于笼统的说法。我会自认为经验丰富,而且我发现 andornot 更易读 — 特别是 not - Konrad Rudolph
1
这不是过度概括,而是一种定义。 :-) - Jerry Coffin

-2

微软的编译器不支持它们。您可以查看关键字列表

这只是一种风格问题(也许会提高可读性,因为有些读者坚持这样做)。就个人而言,我不认为使用它们代替&&和||等有任何优势。


我能理解为什么有些人会混淆&和&&,所以bitand对我很有用。 - anio
@anio 我需要强调一下,不要使用bitand代替&。如果有必要,应该反过来替换逻辑运算符,而不是位运算符。请参见我的其他评论以了解原因。 - Konrad Rudolph

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