【发布时间】:2017-07-30 13:38:54
【问题描述】:
看我的例子here 或者 以下 c++ 和匹配程序集
隐式内联
#include <iostream>
int func(int i)
{
return i * i;
}
int main(int argc, char *argv[]) {
auto value = atoi(argv[1]);
std::cout << func(value);
value = atoi(argv[2]);
std::cout << func(value);
return 1;
}
结果
func(int):
imul edi, edi
mov eax, edi
ret
main:
push rbx
mov rdi, QWORD PTR [rsi+8]
mov rbx, rsi
mov edx, 10
xor esi, esi
call strtol
imul eax, eax
mov edi, OFFSET FLAT:std::cout
mov esi, eax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov rdi, QWORD PTR [rbx+16]
mov edx, 10
xor esi, esi
call strtol
imul eax, eax
mov edi, OFFSET FLAT:std::cout
mov esi, eax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov eax, 1
pop rbx
ret
_GLOBAL__sub_I__Z4funci:
sub rsp, 8
mov edi, OFFSET FLAT:std::__ioinit
call std::ios_base::Init::Init()
mov edx, OFFSET FLAT:__dso_handle
mov esi, OFFSET FLAT:std::__ioinit
mov edi, OFFSET FLAT:std::ios_base::Init::~Init()
add rsp, 8
jmp __cxa_atexit
显式内联
#include <iostream>
inline int func(int i)
{
return i * i;
}
int main(int argc, char *argv[]) {
auto value = atoi(argv[1]);
std::cout << func(value);
value = atoi(argv[2]);
std::cout << func(value);
return 1;
}
结果
main:
push rbx
mov rdi, QWORD PTR [rsi+8]
mov rbx, rsi
mov edx, 10
xor esi, esi
call strtol
imul eax, eax
mov edi, OFFSET FLAT:std::cout
mov esi, eax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov rdi, QWORD PTR [rbx+16]
mov edx, 10
xor esi, esi
call strtol
imul eax, eax
mov edi, OFFSET FLAT:std::cout
mov esi, eax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov eax, 1
pop rbx
ret
_GLOBAL__sub_I_main:
sub rsp, 8
mov edi, OFFSET FLAT:std::__ioinit
call std::ios_base::Init::Init()
mov edx, OFFSET FLAT:__dso_handle
mov esi, OFFSET FLAT:std::__ioinit
mov edi, OFFSET FLAT:std::ios_base::Init::~Init()
add rsp, 8
jmp __cxa_atexit
在示例中,如果注释掉第 5 行,则代码优化会在两个调用点内联函数“func”,但会将 func 的程序集留在生成的二进制文件中。但是,如果 'func' 被显式内联,则该函数在输出程序集中不存在。
为什么 GCC 优化器会在编译后的程序集中留下隐式内联函数,即使内联函数的操作确实与调用代码内联?
【问题讨论】:
-
请在问题中发布您的代码。如果您需要我们的帮助,您应该礼貌地为我们提供帮助。
-
组装怎么样?我使用 Godbolt 的原因是因为它很容易演示正在发生的事情..
-
直接在问题中发布代码。与 Godbolt 等外部资源的链接是不错的附加功能。发布一段代码和一个链接并没有错。
-
inline影响链接,不优化。例如,参见this question。您真正要问的是为什么具有全局链接的函数会离线发出,即使每个实际调用都是内联的。答案可能是,一般来说,很难证明每个调用都会被内联。当然,直到优化器运行之后你才能证明它,这就是忽略运行时链接器等。 -
@Useless - 真的吗?!那么,如果链接器在优化方面做得更好,那么 func 就不会包含在最终程序集中?