考虑:
void* global_ptr;
template<typename T>
void set_global_ptr(T* ptr)
{
global_ptr = ptr;
}
int main()
{
int foo = 123;
float bar = 456;
set_global_ptr(&foo);
set_global_ptr(&bar);
return 0;
}
在带有标志-O3 -fno-inline
的gcc 8.1上,这会被编译为:
void set_global_ptr<int>(int*):
mov QWORD PTR global_ptr[rip], rdi
ret
void set_global_ptr<float>(float*):
mov QWORD PTR global_ptr[rip], rdi
ret
main:
sub rsp, 24
lea rdi, [rsp+8]
mov DWORD PTR [rsp+8], 123
mov DWORD PTR [rsp+12], 0x43e40000
call void set_global_ptr<int>(int*)
lea rdi, [rsp+12]
call void set_global_ptr<float>(float*)
xor eax, eax
add rsp, 24
ret
global_ptr:
.zero 8
Clang 6.0产生类似的东西。我禁用了内联,否则根本就没有生成函数。
如果未使用该类型或进行类型擦除,则应该生成一个实现是有意义的。但是我可以看到生成了set_global_ptr
的两个相同的实现。那是为什么?
我使用Compiler Explorer生成程序集。