Hi all,
Is there any reason why the following code produces the attached assembly code?
struct X { int v; };
int func( X** x, int n )
{
int sum = 0;
while ( n > 0 )
{
sum += (*x)->v;
++x;
–n;
}
return sum;
}
int main() {}
The “func” function is not used, I think it should be omitted by the compiler.
If I change the function to a template function
template
int func( T** x, int n )
{
int sum = 0;
while ( n > 0 )
{
sum += (*x)->v;
++x;
–n;
}
return sum;
}
Then, no code is generated.
Compiled using:
clang++ -S -O3 -std=c++11 -S code.cpp
clang++ --version
clang version 3.5 (trunk 200620)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
Best,
Fernando.
Sorry, here the assembly code
http://pastebin.com/aY8rAXyQ
Hi all,
Is there any reason why the following code produces the attached assembly
code?
struct X { int v; };
int func( X** x, int n )
{
int sum = 0;
while ( n > 0 )
{
sum += (*x)->v;
++x;
--n;
}
return sum;
}
This is an externally visible function - it can't be omitted from the
object file as it may be used by some other object file that will be
linked in. (it could be a global ctor, so the absence of code in
'main' doesn't indicate that it will never be used)
LTO can remove functions like this.
int main() {}
The "func" function is not used, I think it should be omitted by the
compiler.
If I change the function to a template function
template <typename T>
int func( T** x, int n )
{
int sum = 0;
while ( n > 0 )
{
sum += (*x)->v;
++x;
--n;
}
return sum;
}
Then, no code is generated.
Since there's no call, there's no template instantiation, and no code.
The C++ language requires callers in other translation units to have
an instantiation of the template somewhere, it just doesn't have to be
here.
Could be - I'm not particularly familiar with linker flags, though
that's a bit out of scope for this list anyway.
- David
You'll need to tell the linker to dead strip the binary.
-Wl,-dead_strip
since you appear to be on darwin. Otherwise a linker will just assume
that you have that extra code in there for some reason. (This will
slow down the linking process a bit, but not a lot.)
-eric
Hi all,
Is there any reason why the following code produces the attached
assembly code?
struct X { int v; };
int func( X** x, int n )
{
int sum = 0;
while ( n > 0 )
{
sum += (*x)->v;
++x;
--n;
}
return sum;
}
int main() {}
The "func" function is not used, I think it should be omitted by the
compiler.
I guess that's to support separate compilation. The compiler might also need global static analyzing to determine that a function is not used.
If I change the function to a template function
template <typename T>
int func( T** x, int n )
{
int sum = 0;
while ( n > 0 )
{
sum += (*x)->v;
++x;
--n;
}
return sum;
}
Then, no code is generated.
Templates need to be instantiate for their code to be generated. The compiler won't event completely analyze the function unless it's instantiated.
Did you think that "You don't pay for what you don't use" is about dead code? It is not about "use" like "using a function", but about language features.
You are indeed "using" a feature here, and you are paying for (by increasing your code size only). The feature of the language you are using is "I want my function to be externally visible".
Even the linker cannot always optimise these cases (think of a shared library later loaded with dlopen).
Best,
Mehdi
PS: by the way I'm pretty sure an even more simple example with a one line function was possible 