#c #c 11 #assembly #inline #constexpr
#c #c 11 #сборка #встроенный #constexpr
Вопрос:
Я наткнулся на этот потрясающий онлайн-обозреватель компиляторов https://godbolt.org / который показывает ассемблерную версию вашего кода. Я также читал о новых функциях C 11 и узнал о constexpr.
взгляните на квадратную функцию ниже :
constexpr int square(int num) {
return num * num;
}
int main()
{
int result = square(2);
return 0;
}
и следующий код сборки, сгенерированный для двух версий (constexpr и inline)
CONSTEXPR https://godbolt.org/z/c69qrevET
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 4 ; compile time constant 4 = 2*2
mov eax, 0
pop rbp
ret
ВСТРОЕННЫЙ https://godbolt.org/z/czaKT8fhY
square(int):
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov eax, DWORD PTR [rbp-4]
imul eax, DWORD PTR [rbp-4]
pop rbp
ret
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov edi, 2
call square(int)
mov DWORD PTR [rbp-4], eax
mov eax, 0
leave
ret
Я везде читал, что подобные функции могут быть встроены, но почему в версии asm есть код вызова функции? Согласно встроенному определению, этого следует избегать, верно?
Ответ №1:
constexpr
выполнение функций во время компиляции не гарантируется, если они не используются в контексте, где требуется постоянное выражение. Измените свой код на
int main()
{
constexpr int result = square(2);
return 0;
}
и вы увидите разницу, потому constexpr
что переменные требуют инициализации с помощью постоянного выражения.
Обратите внимание, что уровень оптимизации также имеет значение.
Комментарии:
1. Полезно это знать. Спасибо.
2. @Ankitsinghkushwah: если это ответ на ваш вопрос, пожалуйста, нажмите зеленую галочку, чтобы отметить его как ответ.
3. Вызов
constexpr
функции уже оценивается GCC во время компиляции, это «встроенная» функция, которая не является. (С отключенной оптимизацией). Кроме того, правило «как если бы» позволяет компилятору выполнять оценку во время выполнения, если он этого хочет. Только такие случаи, какint foo[square(2)];
в качестве члена структуры или в глобальной области видимости, не дадут GCC никакой возможности, даже для действительно сложнойconstexpr
функции, которую он мог бы в противном случае (особенно при низком уровне оптимизации) вызвать во время выполнения. Итак, ключевая часть вашего ответа заключается в том, что «уровень оптимизации имеет значение».