开发者

Strange linking behavior, latest g++

I have been running into strange linking behavior with g++, however, I'm just a student, and I was wondering if this was normal.

I am trying to link assembly code (machine: fedora 14 gnome 32bits x86 i686 intel i7) with c++ code and to have the assembly code call a method from a fonction instanciated in the c++ file. It seems that implementing a method in the class declaration will prevent it from being put in the linker table unless it's used at least once in the original source.

class A
{
public:
    void showSUP() {
        cout<<"sup";
    }
};

After instanciating A, you will not be able to call _ZN1A7showSUPEv because it has not been put in the linking table:

call _ZN1A7showSUPEv

However, if you call A::showSUP() in the same .cpp as A was declared, then calling it from a seperate assembly file will work.

With (and instantiation of A)

class A
{
    void showSUP();
};

A::showSUP()
{
    cout<<"sup";
}

Calling 开发者_JS百科_ZN1A7showSUPEv will work.

My question is, why doesn't the first example work.

Thank you all in advance.


There are attributes, that you can specifify for a function in this way

classe A
{
  public:
    void showSUP(){
      cout<<"sup";
    } __attribute__((used))
};

see gcc attribute overview

used Found in versions: 3.1-3.4 Description:

     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.


  • For inlined functions the compiler will only output code where the function is used.
  • Functions defined inside the class definition are inline (usually).
  • The function isn't used.
  • Therefore: no function in the binary.


In general, if you want a function to be included in the final library / executable, it need be:

  • used
  • non-inlined

And inlined function is a function whose code is simply copied and pasted where the function is used (by the compiler) so that there is no function call. It's an opportunity optimization, so a function may be inlined in some places and not inlined in others, depending on the context. Most very short functions (so-called one-liners) are generally inlined.

In the old times, to be inlined a function needed be defined in the current translation unit, that is:

  • either it is defined in the header (like is your case), and thus can be inlined in all sources including this header
  • either it is defined in a source file, and thus can be inlined in this source file

Nowadays though we also have LTO (Link Time Optimization), and if activated the linker may actually inline function calls. Those optimizations are also responsible for cleaning up the resulting library/binary from unused symbols.

There are two possible solutions to your issue:

  • define the function in a source file instead, it is standard and may not be wiped out
  • use compiler specific attributes to mark the function as used, so that it's not wiped out

In the latter case, if you wish for portability, I can only advise using a macro (ATTRIBUTE_USED) and define its content depending on the current compiler used.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜