为什么-LLONG_MIN会导致未定义的行为?C11,6.5.3.3p3:一元运算符的结果是其(提升)操作数的负数。整数提升是在操作数上执行的,结果具有提升类型。这里我们看到C标准不要求实现一元运算符-,例如,使用按位-not后跟adding 1,其中“adding 1”可能会导致未定义的行为。如何从引用的文本中推断出-LLONG_MIN导致未定义的行为?
-LLONG_MIN
zwghvu4y1#
如何从引用的文本中推断-LLONG_MIN导致未定义的行为?单从引文中是无法推断出这一点的,然而,这一系列的推理就足够了:
LLONG_MIN
LLONG_MAX
long long int
如果在表达式求值过程中出现 exceptional condition(即,如果结果没有数学定义或不在其类型的可表示值范围内),则行为未定义。
nwlls2ji2#
如何从引用的文本中推断出-LLONG_MIN导致未定义的行为?这是不可能推断出它从引用的文本.你还需要这个文本https://port70.net/~nsz/c/c11/n1570.html#6.5p5:如果在表达式求值过程中出现异常条件(即,如果结果未在数学上定义或不在其类型的可表示值范围内),则行为未定义。在-LLONG_MIN的数学结果不能用long long类型表示的实现中,此规则被触发,行为未定义。
long long
6ioyuze23#
正如其他答案所指出的那样,这种情况在6.5-5段中有所涉及,该段说,如果结果不能由其类型表示,则行为是未定义的。一般来说,未定义的行为可能是C标准中没有定义(提到)的行为,但在这种情况下,标准是非常明确的。当涉及到有符号整数类型时,C18标准(及更早版本)允许3种表示(第6.2.6.2-2节)
在“二补数”表示中,最小可表示值的负值是不可表示的(它将比最大可表示值多一个)。用“符号和大小”和“一个的补数”,最小可表示值的负值是可表示的(它将等于最大可表示值)。因此,-LLONG_MIN是未定义的行为,当且仅当实现使用“二进制补码”表示时。由于该标准因此允许实现这是未定义的行为,因此该行为在该标准中是未定义的。在标准未定义行为的情况下,总是允许实现定义行为,但在这种情况下,标准明确地描述了一组具有-LLONG_MIN定义行为的实现(那些不使用带符号整数的二进制补码表示的实现)。如果实现有-LLONG_MAX==LLONG_MIN,可以通过静态Assert来检查,但它几乎没有实际用途,因为2的补码表示是目前最常见的。即将到来的C2 x标准将只允许2的补码表示(第6.2.6.2-2节)。因此,对于C2 x,-LLONG_MIN将始终是标准中未定义的行为。
-LLONG_MAX==LLONG_MIN
3条答案
按热度按时间zwghvu4y1#
如何从引用的文本中推断
-LLONG_MIN
导致未定义的行为?单从引文中是无法推断出这一点的,然而,这一系列的推理就足够了:
LLONG_MIN
为− 9,223,372,036,854,775,808,而LLONG_MAX
为9,223,372,036,854,775,807(C 2018 5.2.4.2.1 1)。LLONG_MIN
和LLONG_MAX
具有这些值。(我假设读者熟悉2的补码,并且标准允许2的补码。)-LLONG_MIN
的指定标称结果将是9,223,372,036,854,775,808(C 2018 6.5.3.3 3)。LLONG_MIN
的类型是long long int
(C 2018 5.2.4.2.1 1),-LLONG_MIN
的结果的类型是long long int
(C 2018 6.5.3.3 3和6.3.1.1)。long long int
表示(由于LLONG_MIN
和LLONG_MAX
的含义)。如果在表达式求值过程中出现 exceptional condition(即,如果结果没有数学定义或不在其类型的可表示值范围内),则行为未定义。
nwlls2ji2#
如何从引用的文本中推断出-LLONG_MIN导致未定义的行为?
这是不可能推断出它从引用的文本.你还需要这个文本https://port70.net/~nsz/c/c11/n1570.html#6.5p5:
如果在表达式求值过程中出现异常条件(即,如果结果未在数学上定义或不在其类型的可表示值范围内),则行为未定义。
在
-LLONG_MIN
的数学结果不能用long long
类型表示的实现中,此规则被触发,行为未定义。6ioyuze23#
正如其他答案所指出的那样,这种情况在6.5-5段中有所涉及,该段说,如果结果不能由其类型表示,则行为是未定义的。
一般来说,未定义的行为可能是C标准中没有定义(提到)的行为,但在这种情况下,标准是非常明确的。
当涉及到有符号整数类型时,C18标准(及更早版本)允许3种表示(第6.2.6.2-2节)
在“二补数”表示中,最小可表示值的负值是不可表示的(它将比最大可表示值多一个)。
用“符号和大小”和“一个的补数”,最小可表示值的负值是可表示的(它将等于最大可表示值)。
因此,
-LLONG_MIN
是未定义的行为,当且仅当实现使用“二进制补码”表示时。由于该标准因此允许实现这是未定义的行为,因此该行为在该标准中是未定义的。
在标准未定义行为的情况下,总是允许实现定义行为,但在这种情况下,标准明确地描述了一组具有
-LLONG_MIN
定义行为的实现(那些不使用带符号整数的二进制补码表示的实现)。如果实现有
-LLONG_MAX==LLONG_MIN
,可以通过静态Assert来检查,但它几乎没有实际用途,因为2的补码表示是目前最常见的。即将到来的C2 x标准将只允许2的补码表示(第6.2.6.2-2节)。因此,对于C2 x,
-LLONG_MIN
将始终是标准中未定义的行为。