__builtin_is_constant_evaluated
- это встроенная функция, используемая для реализации std::is_constant_evaluated
в стандартной библиотеке для clang и gcc.
Код, который недопустим в постоянном контексте, также часто сложнее оптимизатору для постоянного сворачивания.
например:
int f(int i) {
if (__builtin_is_constant_evaluated())
return 1;
else {
int* ptr = new int(1);
int i = *ptr;
delete ptr;
return i;
}
}
испускается gcc -O3
как:
f(int):
sub rsp, 8
mov edi, 4
call operator new(unsigned long)
mov esi, 4
mov rdi, rax
call operator delete(void*, unsigned long)
mov eax, 1
add rsp, 8
ret
, поэтому оптимизатор использовал __builtin_is_constant_evaluated() == 0
clang foldэто константа, но это потому, что оптимизатор clang может удалить ненужное динамическое выделение, а не потому, что он использовал __builtin_is_constant_evaluated() == 1
.
. Я знаю, что это приведет к тому, что возвращаемое значение реализации __builtin_is_constant_evaluated()
будет определено, поскольку оптимизация будет отличаться отодин компилятор другому.но is_constant_evaluated уже следует использовать только в том случае, если оба пути имеют одинаковое наблюдаемое поведение.
почему оптимизатор не использует __builtin_is_constant_evaluated() == 1
и откат до __builtin_is_constant_evaluated() == 0
, если он не смог сложить?