gpt4 book ai didi

gcc - 赋值 : still not implemented in GCC? 中的 C++17 排序

转载 作者:行者123 更新时间:2023-12-04 09:43:45 24 4
gpt4 key购买 nike

我尝试了以下代码作为实现 R 交换的幼稚尝试和 B ABGR 中的字节数单词

#include <stdio.h>
#include <stdint.h>

uint32_t ABGR_to_ARGB(uint32_t abgr)
{
return ((abgr ^= (abgr >> 16) & 0xFF) ^= (abgr & 0xFF) << 16) ^= (abgr >> 16) & 0xFF;
}

int main()
{
uint32_t tmp = 0x11223344;
printf("%x %x\n", tmp, ABGR_to_ARGB(tmp));
}

令我惊讶的是,这段代码在 C++17 模式下的 GCC 中“有效”——字节被交换

http://coliru.stacked-crooked.com/a/43d0fc47f5539746

但它不应该交换字节! C++17 明确指出,赋值的 RHS 应该在 LHS 之前 [完全] 排序,这也适用于复合赋值。这意味着在上面的表达式中,每个 ^= 的每个 RHS应该使用 abgr 的原始值.因此最终结果是 abgr应该简单地有 B字节由 R 异或字节。这就是 Clang 似乎产生的东西(有趣的是,带有排序警告)

http://coliru.stacked-crooked.com/a/eb9bdc8ced1b5f13

快速浏览 GCC 程序集

https://godbolt.org/g/1hsW5a

表明它似乎是倒序排列的:LHS 在 RHS 之前。这是一个错误吗?或者这是海湾合作委员会的某种有意识的决定?还是我误解了什么?

最佳答案

int a = 1; (a += a) += a; 表现出完全相同的行为,GCC 为其计算 a == 4之后和 clang a == 3 .

标准的这一部分(来自工作草案 N4762)产生了潜在的歧义:

[expr.ass]: 7.6.18 Assignment and compound assignment operators

Paragraph 1: The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand; their result is an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. The right operand is sequenced before the left operand. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation.

Paragraph 7: The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once. In += and -=, E1 shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type. In all other cases, E1 shall have arithmetic type.



GCC 似乎正在使用此规则进行内部转换 (a += a) += a(a = a + a) += aa = (a = a + a) + a (因为 a = a + a 必须只计算一次) - 对于这个表达式,排序规则被正确应用。

然而,Clang 似乎以不同的方式执行最后一个转换步骤: auto temp = a + a; temp = temp + a; a = temp;
两个编译器都对此发出警告(来自原始代码):
  • 海湾合作委员会:warning: operation on 'abgr' may be undefined [-Wsequence-point]
  • 叮当:warning: unsequenced modification and access to 'abgr' [-Wunsequenced]

  • 所以编译器作者知道这种歧义并决定不同的优先级(GCC:第 7 段>第 1 段;clang:第 1 段>第 7 段)。

    这似乎是标准中的一个缺陷。

    关于gcc - 赋值 : still not implemented in GCC? 中的 C++17 排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51511102/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com