有些尴尬,但是在C++标准中,按位与运算符定义如下(重点在于)。
进行通常的算术转换; 结果是其操作数的按位与函数。这个运算符仅适用于整数或无作用域枚举操作数。
对我来说,这看起来有点毫无意义。就我所知,在标准中没有定义“按位与函数”。
我理解“与函数”很容易理解,因此可能不需要解释。单词“按位”的含义应该也相当清楚:该函数应用于其操作数的相应位。但是,构成操作数的位不清楚。
怎么回事?
有些尴尬,但是在C++标准中,按位与运算符定义如下(重点在于)。
进行通常的算术转换; 结果是其操作数的按位与函数。这个运算符仅适用于整数或无作用域枚举操作数。
对我来说,这看起来有点毫无意义。就我所知,在标准中没有定义“按位与函数”。
我理解“与函数”很容易理解,因此可能不需要解释。单词“按位”的含义应该也相当清楚:该函数应用于其操作数的相应位。但是,构成操作数的位不清楚。
怎么回事?
并且缺陷报告1943说:
CWG在2014-06(Rapperswil)会议上决定仅解决1857和1861问题引发的一小部分问题。本问题是剩余问题的占位符,例如通过2 n 的值定义“位”,指定位字段是否具有符号位等。
从这个缺陷报告1796:对于空字符,“所有位都为零”是否是有意义的要求?可以看出,标准引用位时所指的意思也影响到其他部分:
根据2.3 [lex.charset]第3段,基本执行字符集和基本执行宽字符集应包含基本源字符集的所有成员,以及表示警报、退格和回车的控制字符,加上一个空字符(分别是 null 宽字符),其表示具有所有零位。不清楚便携式程序是否可以检查表示的位;相反,似乎只能检查对应于值表示的数字的位(参见3.9.1 [basic.fundamental]第1段)。更合适的做法可能是要求空字符值等于0或'\0',而不是指定表示的位模式。对于移位、按位与和按位或运算符的定义也存在类似问题:这些规范是关于表示的位模式的约束还是关于将这些模式解释为数字后产生的值的约束?在这种情况下,解决方案是将“表示具有所有零位”更改为“值为0”。3.9.1
节[basic.fundamental]的第3
段中确实参照了C标准的第5.2.4.2.1
节,但它并未参考C标准的第6.5/4
节,后者至少可以告诉我们结果是实现定义的。我在下面的评论中解释了C++标准只能明确地包含规范参考文本。6.5/4
,因为它在C++标准中没有明确引用,请参见Can we apply content not explicitly cited from the normative references to the C++ standard?。 - Shafik Yaghmourchar
标记[例如,因为wchar_t具有由编译器设置的填充位],这是合法的。 - supercat[basic.fundamental]/3指的是C++标准中基本概念部分的第3节,与C 5.2.4.2.1相对应。由于C++中位运算符的不充分规定,因此在这种情况下,应该类似地参考C标准6.5.10/4:
二进制 & 运算符的结果是操作数的按位AND(即,仅当转换后的操作数的相应位均设置时,结果中的每个位才设置)。
请注意,C 6.5/4中有:
某些运算符(一元运算符 ~ 和二元运算符 <<、>>、&、^ 和 |,统称为“位运算符”)需要具有整数类型的操作数。这些运算符产生依赖于整数的内部表示的值,并且对于有符号类型,具有实现定义和未定义的方面。
整数的内部表示当然在6.2.6.2/1、/2中描述。
being underspecified should similarly defer to C, in this case 6.5.10/4
...除非明确规定,否则C++标准不能推迟到C标准,请参见此处。尽管我可以自信地说这可能是意图。 - Shafik Yaghmour从法律上讲,我们可以认为所有按位操作都具有未定义的行为,因为它们实际上没有定义。
更合理的做法是运用常识并参考这些操作的常见含义,将其应用于操作数的位(因此称为“按位”)。
但事实上并没有明确规定。遗憾的是,我的答案不能被视为规范措辞。
(0 | 5)
成为除5以外的其他值,因为int类型有超过4位。我不是说你错了,我只是想理解。 - fjardon
-1
解释为首先进行计算,在2的补码表示下,并且类型转换不改变值,则结果为0xFFFFFFFF&0x00000002
,即2。 - Hot Licks