【问题标题】:unary - operator: implementation defined or undefined一元 - 运算符:实现定义或未定义
【发布时间】:2011-11-02 07:54:42
【问题描述】:
unsigned u = 1;
int i = -u;

第二个赋值是否在 6.5.5 之下:如果在计算表达式期间出现异常情况(即,如果结果未在数学上定义或 不在其类型的可表示值范围内),行为是未定义

或者它是否属于 6.3.1.3: 1 当整数类型的值被转换为_Bool以外的其他整数类型时,... ... 3 否则,新类型是有符号的,值不能在其中表示;无论是 结果是实现定义的或产生了实现定义的信号。


我写这个问题是因为以下(感谢 R.. 的澄清)在 6.5.5 下生成 undefined 行为:

int i = INT_MIN;
i = -i;

上面的问题是表达式-i 的类型是int-INT_MIN 对于2 的补码平台可能大于INT_MAX。在这种情况下,它会产生未定义的行为。

另一方面,对于:

unsigned u = 1;
int i = -u;

-u 是无符号类型。正如Is unsigned integer subtraction defined behavior? 中所解释的,尽管无符号的范围名义上是从 0 到 UINT_MAX,但实际上不存在超出范围的无符号值。所以6.5.5不适用于-u。但是我们仍然有赋值表达式 i=-u 在这种情况下适用 6.3.1.3。

或者换一种说法,如果我可以改写 6.5.5,那就是: 如果在计算表达式期间出现异常情况(即,如果结果没有在数学上定义或不在其类型的可表示值范围内),如果表达式类型不是标准类型或扩展类型之一无符号类型,行为未定义。 如果表达式类型为标准或扩展无符号类型之一,且结果小于0或大于最大可表示值,则按6.3.1.3/2调整结果。 p>

【问题讨论】:

    标签: c expression standards


    【解决方案1】:

    它属于 6.3.1.3。表达式-u 没有什么特别之处。它等于UINT_MAX。将结果分配给无法表示值 UINT_MAX 的有符号类型,然后会导致实现定义的转换或信号。

    【讨论】:

    • 但 6.3.1.3 仅适用于转换为另一种整数类型的情况。我认为这意味着转换前后的类型必须不同。那么在-u的评测中,只有6.5.5适用?
    • 转换是作业的一部分。 6.5.5 根本不适用,因为 -u 在其类型 (unsigned int) 的可表示值范围内。
    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 2021-06-11
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    相关资源
    最近更新 更多