标签: assumption

当假设 [[assume]] 包含 UB 时会发生什么?

在 C++23 中,该[[assume(expression)]]属性使得如果表达式false,则行为未定义。例如:

int div(int x, int y) {
    [[assume(y == 1)]];
    return x / y;
}
Run Code Online (Sandbox Code Playgroud)

y这会编译成与始终相同的代码1

div(int, int):
        mov     eax, edi
        ret
Run Code Online (Sandbox Code Playgroud)

但是,如果存在另一级别的未定义行为,会发生什么情况?

int div(int x, int y) {
    [[assume(x / 0 == 1)]];
    return x / y;
}
Run Code Online (Sandbox Code Playgroud)

现在假设里面有UB,但是假设没有被评估。这是什么意思?这只是无稽之谈还是编译器可以用这个假设做任何事情?

c++ language-lawyer c++23 assumption

23
推荐指数
2
解决办法
1037
查看次数

为 GCC 复制 clang 的 __builtin_assume

最近,我发现void __builtin_assume(bool)了 clang,它可以向编译器提供有关程序状态的附加信息。这可以产生巨大的差异,例如

#include <cstddef>

// compiles to about 80 instructions at -O3
unsigned sum(unsigned data[], size_t count) {
    unsigned sum = 0;
    for (size_t i = 0; i < count; ++i) {
        sum += data[i];
    }
    return sum;
}

// compiles to about 10 instructions at -O3
unsigned sum_small(unsigned data[], size_t count) {
    __builtin_assume(count <= 4);
    unsigned sum = 0;
    for (size_t i = 0; i < count; ++i) {
        sum += data[i];
    }
    return …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang built-in assumption

6
推荐指数
2
解决办法
3571
查看次数

为什么[[假设]]不被评估但也可能被评估?

cppreference页面[[assume]]说:

[[assume( expression )]] 
Run Code Online (Sandbox Code Playgroud)

[...] 表达式没有被求值(但它仍然可能被求值)。

这个措辞让我很困惑。这里 cppreference 错了吗?如果不评估,为什么可能会评估?它不是像 中的表达式一样未计算的操作数吗sizeof?如果不可以,后果是什么?

c++ attributes language-lawyer c++23 assumption

6
推荐指数
1
解决办法
170
查看次数

如果假设,即 [[assume]] 在常量表达式中失败,会发生什么?

在 C++23 中,该[[assume(conditonal-expression)]]属性使得如果条件表达式的计算结果不为true,则行为未定义。例如:

int div(int x, int y) {
    [[assume(y == 1)]];
    return x / y;
}
Run Code Online (Sandbox Code Playgroud)

y这会编译成与始终相同的代码1

div(int, int):
        mov     eax, edi
        ret
Run Code Online (Sandbox Code Playgroud)

正如评论者所指出的,这不是必需的优化;这正是 GCC 碰巧处理的信息,除了y == 1UB 之外什么都没有。

编译器完全忽略所有假设是有效的。

但是常量表达式呢?

编译器需要诊断常量表达式1)中所有未定义的行为,但这合理吗?例如:

constexpr bool extremely_complicated(int x) {
    bool result;
    // 10,000 lines of math ...
    return result;
}

constexpr int div(int x, int y) {
    // This should result in a compiler error when the compiler …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constant-expression c++23 assumption

1
推荐指数
1
解决办法
212
查看次数