Reputation: 235
Working on OSX with llvm and lldb, I have the following code:
#include <stdio.h>
class A{
public:
void f() __attribute__((noinline))
{
printf("f()\n");
}
void g() __attribute__((noinline))
{
printf("g()\n");
}
};
int main()
{
A a;
a.g();
return 0;
}
When breaking in main(), and trying to call p a.f()
from the debugger I get:
error: Couldn't lookup symbols: __ZN1A1fEv
calling p g.f()
, however, works well.
I understand that f() may be optimized away, but is there any way to disable this optimization, so I can use it in the debugger anyway?
Thanks!
Upvotes: 3
Views: 340
Reputation: 1727
While moving the definition out of line may help in some cases, it won't help in all cases, e.g. if it's not an odr c++ member function but rather just a static function or if your entire program is LTO optimized and the function isn't referenced outside of the local translation unit.
In those cases (and probably this one as well) you should instead mark the function as __attribute__((used))
to tell the compiler that the function is used and to make sure and generate code for it in the resulting object file - which also means that debug information will be generated as well.
Your final code for this will end up looking like:
#include <stdio.h>
class A {
public:
void f() __attribute__((noinline, used))
{
printf("f()\n");
}
void g() __attribute__((noinline))
{
printf("g()\n");
}
};
int main()
{
A a;
a.g();
return 0;
}
This is one of the reasons why __attribute__((used))
was designed. From the gcc documentation:
This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced. This is useful, for example, when the function is referenced only in inline assembly. When applied to a member function of a C++ class template, the attribute also means that the function is instantiated if the class itself is instantiated.
This means that the function will be guaranteed to be emitted in all cases even if it isn't used.
(As a further addendum I haven't verified that this will actually work for LTO optimization - it probably should, but I'm betting it's a corner case that isn't often thought of, I didn't until just now and I work on LTO :)
Upvotes: 2
Reputation: 87391
Move the definition of f
outside the class:
#include <stdio.h>
class A {
public:
void f();
void g() __attribute__((noinline))
{
printf("g()\n");
}
};
void A::f()
{
printf("f()\n");
}
int main()
{
A a;
a.g();
return 0;
}
This has worked for me with $ g++ t.cc
and $ g++ -g t.cc
on Linux with gcc 4.8.4. It may work with your toolchain as well.
$ g++ t.cc
$ nm a.out | grep _ZN1A
000000000040052e T _ZN1A1fEv
0000000000400562 W _ZN1A1gEv
As an alternative, as described in echristo's answer, add used
to the attributes of f
, and keep it inside the class. That also works with $ g++ t.ccand
$ g++ -g t.cc`:
$ g++ -g t.cc
0000000000400548 W _ZN1A1fEv
0000000000400560 W _ZN1A1gEv
Adding used
also works with g++ -O2 -g t.cc
.
Upvotes: 1