having multiple copies of _GLOBAL__sub_I__xxxx which are calling std::ios_base::Init::Init()@GLIBCXX_3.4

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I see that gcc emits for every function which uses cout a global constructor call is emitted, even if the function is removed later during link stage.

Following example project:

func.cpp:
#include<iostream>
void myfunc() { std::cout << "Hallo func " << std::endl; }

func2.cpp:
#include<iostream>
void myfunc2() { std::cout << "Func2 called" << std::endl; }

header files simply declare that functions and the

main.cpp:
#include "func.h"
#include "func2.h"

int main()
{
    //myfunc();
    //myfunc2();
}

Makefile:
all: go

CXX=/opt/linux-gnu_7.1.0/bin/c++

%.o: %.cpp
    $(CXX) -O3 -fdata-sections -ffunction-sections $< -c

go: main.o func.h func.o func2.o func2.h
    $(CXX) -O3 -fdata-sections -ffunction-sections main.o func.o func2.o -o go -Wl,--gc-sections 

clean:
    rm -f *.o
    rm -f go

If I disassemble the final executable I see multiple copies of the initializers for which all a exact copy:
0000000000400550 <_GLOBAL__sub_I__Z6myfuncv>:
  400550:   48 83 ec 08             sub    $0x8,%rsp
  400554:   bf 39 10 60 00          mov    $0x601039,%edi
  400559:   e8 c2 ff ff ff          callq  400520 <std::ios_base::Init::Init()@plt>
  40055e:   ba 30 10 60 00          mov    $0x601030,%edx
  400563:   be 39 10 60 00          mov    $0x601039,%esi
  400568:   bf 30 05 40 00          mov    $0x400530,%edi
  40056d:   48 83 c4 08             add    $0x8,%rsp
  400571:   e9 9a ff ff ff          jmpq   400510 <__cxa_atexit@plt>
  400576:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  40057d:   00 00 00

0000000000400580 <_GLOBAL__sub_I__Z7myfunc2v>:
  400580:   48 83 ec 08             sub    $0x8,%rsp
  400584:   bf 3a 10 60 00          mov    $0x60103a,%edi
  400589:   e8 92 ff ff ff          callq  400520 <std::ios_base::Init::Init()@plt>
  40058e:   ba 30 10 60 00          mov    $0x601030,%edx
  400593:   be 3a 10 60 00          mov    $0x60103a,%esi
  400598:   bf 30 05 40 00          mov    $0x400530,%edi
  40059d:   48 83 c4 08             add    $0x8,%rsp
  4005a1:   e9 6a ff ff ff          jmpq   400510 <__cxa_atexit@plt>
  4005a6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  4005ad:   00 00 00

Is it a bug, that every function emmits a exact copy for calling std::ios_base::Init::Init()@plt ? It is only needed once but emmited for each function. This wastes a lot of program space. In addition for my example, I removed the call to my functions so there is no place anymore where I need iostream operations. But the code is still present, also if the requiring functions are not linked in.

As I understand using -ffunction-section generates a .text.xxx section for every function but the initializers go to .text.startup._GLOBAL__sub_I__Z6myfuncv. But as I see I can't remove that unused sections? Why?

The in general: Why we need for every function using cout a initializer emmited to the code? Is there any chance to remove the generated duplicates can be reduced to a single one or maybe removed completely if no user if cout remains after linking? Maybe is there a optimizer flag for the linker?

Regards
 Klaus





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux