G++ generates code for unused template specializations?

你离开我真会死。 提交于 2019-12-03 03:25:01
Robᵩ

The template specializations in your example are functions with external linkage. The compiler cannot know that they won't be called from another translation unit.

On my g++ 4.7.2 Ubuntu system, placing the templates into an anonymous namespace and compiling with -O3 prevented the unused function from being generated.

Similarly, declaring the function template static had the desired effect.

thang

This is a peculiar problem. I looked into it a little, and this issue is unrelated to template specialization. I guess g++ doesn't, by default, strip unused symbols. This makes sense in case you later want to link your output to another program.

However, there are command line options that you can use to strip unused symbols. For details, see this post:

How to remove unused C/C++ symbols with GCC and ld?

but also see here

Using GCC to find unreachable functions ("dead code")

and here

Dead code detection in legacy C/C++ project

Just to try this out, I modified the code as follows:

#include <iostream>

void junk_function() {
    std::cout<<"test" << std::endl;    
}

template <int size>
void special_function()
{
     std::cout << "Called without specialization: " << size << std::endl;
}

template <>
void special_function<4>()
{
     std::cout << "dword" << std::endl;
}

template <>
void special_function<8>()
{
     std::cout << "qword" << std::endl;
}

int main()
{
     special_function<sizeof(int)>();
     return 0;
}

Then stored this code to sp.cpp. First,

g++ -Os sp.cpp -o sp
nm sp

and got this (note, I removed a bunch of symbols for readability):

0804879a T _Z13junk_functionv
080487b8 T _Z16special_functionILi4EEvv
080487f5 T _Z16special_functionILi8EEvv

Seems the two unused symbols are there. I also tried -O1, -O2, -O3, and got the same.

Next:

g++ -Os -fdata-sections -ffunction-sections sp.cpp -o sp -Wl,--gc-sections
nm sp

and got this:

0804875a T _Z16special_functionILi4EEvv

That's it. So it looks like you just need to pass the right arguments in to tell g++ to strip unused symbols. On mac, I guess they have the -dead_strip option, but I don't know why it doesn't work in g++ (even though it is mentioned in the man pages. Admittedly, I didn't dig into this, so there may be a fine print that I missed).

I think Visual C++'s linker strips by default when you link, but I didn't test. Maybe someone else can chime in.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!