1

I'm developing an application and a library using SourceryGpp lite for arm.

I'm not using standard libs or default start files. So to call the global ctrs i'm doing to following code:

ldr r0,=__ctors_init__
ldr r0,[r0]
mov lr,pc
bx r0

So the problem is that I'm defining some global instances in the static library, but the their ctors are never called by the above code. The weird thing is that the global ctors of the application are successfully called, anyone knows why?

DVD
  • 1,744
  • 3
  • 17
  • 34

2 Answers2

5

This is a well known problem with static libraries and global variables with runtime initialization.

Most linkers will only include components of the static library that are needed to fulfill a dependency of the main program. If none of the objects in the compilation unit are used, the linker removes never adds the compilation unit as a whole, and side effects of global initialization do not occur.

There's a good explanation here (final summary here)

You would have the same problem with the standard library-provided startup code.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • But is there any solution to this problem without the application code refer the static library instances? – DVD Jun 11 '11 at 20:12
  • @DVD: Unity build solves it (because there's only one compilation unit in the library). Getting rid of the library and just passing all the files that make up the library on the command line works well. And of course you can refer to the variables from the main program so they get pulled in at link time. – Ben Voigt Jun 11 '11 at 20:38
3

The standard explicitly permits to defer static objects initialization (C++98, [basic.start.init]):

It is implementation-defined whether or not the dynamic initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first use of any function or object defined in the same translation unit as the object to be initialized.

(latest C++0x draft has a bit different wording.)

So if you don't use some translation unit at-all, all the objects defined there may be removed completely.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • Good point (+1), although the code he's writing is where the deferral would have to take place, so in his case there's no deferral. The initializers just aren't on the global initializer list because the linker didn't pull in those translation units from the library. – Ben Voigt Jun 11 '11 at 19:10