Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Order of initialization of static libraries in gcc

44 views
Skip to first unread message

Paavo Helde

unread,
Sep 26, 2022, 6:36:59 AM9/26/22
to

I know the order of TU-s is not determined when initializing the global
statics. But what about static libraries? Are the global statics in
static libraries initialized in the order I list the libraries on the
linker command-line? If so, it seems the needed order would be in
general opposite to the order needed for symbol resolving dependencies.

I'm specifically interested in an answer for gcc, as this is where a
third-party library was failing. For now it looks like I resolved the
issue by re-shuffling and duplicating the static lib names in the link
command line, but I wonder how permanent this fix is.




Bonita Montero

unread,
Sep 26, 2022, 7:38:01 AM9/26/22
to
Am 26.09.2022 um 12:36 schrieb Paavo Helde:
>
> I know the order of TU-s is not determined when initializing the global
> statics. But what about static libraries? Are the global statics in
> static libraries initialized in the order I list the libraries on the
> linker command-line? If so, it seems the needed order would be in
> general opposite to the order needed for symbol resolving dependencies.

As there are usually no dependencies on the other global
objects outside the library that's actually not a problem.

Paavo Helde

unread,
Sep 26, 2022, 8:18:53 AM9/26/22
to
26.09.2022 14:38 Bonita Montero kirjutas:
> Am 26.09.2022 um 12:36 schrieb Paavo Helde:
>>
>> I know the order of TU-s is not determined when initializing the
>> global statics. But what about static libraries? Are the global
>> statics in static libraries initialized in the order I list the
>> libraries on the linker command-line? If so, it seems the needed order
>> would be in general opposite to the order needed for symbol resolving
>> dependencies.
>
> As there are usually no dependencies on the other global
> objects outside the library that's actually not a problem.

Except when there is (a problem). You do not need a dependency on a
global object, just calling a function using the non-constructed global
object is enough.

For fun, here are snippets from the concrete library which suddenly
started to fail:

Library aws-crt-cpp:

source file Api.cpp, namespace level
Allocator *g_allocator = Aws::Crt::DefaultAllocator();

source file allocator.c:

void *aws_mem_acquire(struct aws_allocator *allocator, size_t size) {
AWS_FATAL_PRECONDITION(allocator != NULL); // <----- FAILS -----
// ...
}

header file StlAllocator.h

extern AWS_CRT_CPP_API Allocator *g_allocator;

template <typename T> class StlAllocator :
public std::allocator<T>
{
public:
StlAllocator() noexcept : Base()
{ m_allocator = g_allocator; }

// ...
Allocator *m_allocator;
};


Library aws-cpp-sdk-core:

Header file AWSString.h:

using String = std::basic_string< char, std::char_traits< char >,
Aws::Allocator< char > >;

Source file AWSConfigFileProfileConfigLoader.cpp, namespace level:

const Aws::String IDENTIFIER_ALLOWED_CHARACTERS =
R"(%+-./0123456789:@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz)";



Andrey Tarasevich

unread,
Sep 26, 2022, 4:19:37 PM9/26/22
to
On 9/26/2022 3:36 AM, Paavo Helde wrote:
>
> I know the order of TU-s is not determined when initializing the global
> statics. But what about static libraries? Are the global statics in
> static libraries initialized in the order I list the libraries on the
> linker command-line?

Huh? What is "initialization of a static library"? There is no such
concept. There's no need for such a concept.

A static library is a just an archive of object files. All you do with a
static library is pull one or more object files from that archive. A
static library has no other presence in the translation process. It does
not affect anything.

Object files from static library map to the language-level concept of
*translation units* is exactly the same way as ordinary standalone
("library-less") object files do.

In other words, the matters of order-of-initialization work the same way
for standalone translation units and for translation units packed into a
library. They all live in one global flat universe. Placing something
into a static library has absolutely no effect on the matters of global
order-of-initialization.

In short, when you pack a translation unit (i.e. an object file) into a
static library, it changes absolutely nothing. Static libraries do not
have initialization.

--
Best regards,
Andrey

Scott Lurndal

unread,
Sep 26, 2022, 5:54:44 PM9/26/22
to
Andrey Tarasevich <andreyta...@hotmail.com> writes:
>On 9/26/2022 3:36 AM, Paavo Helde wrote:
>>
>> I know the order of TU-s is not determined when initializing the global
>> statics. But what about static libraries? Are the global statics in
>> static libraries initialized in the order I list the libraries on the
>> linker command-line?
>
>Huh? What is "initialization of a static library"? There is no such
>concept. There's no need for such a concept.
>
...

>
>In short, when you pack a translation unit (i.e. an object file) into a
>static library, it changes absolutely nothing. Static libraries do not
>have initialization.

In the context of executing constructors for statically defined
objects, the order is indeterminate, whether the application is
fully linked (i.e. static libraries) or dynamically linked.

Bonita Montero

unread,
Sep 26, 2022, 9:47:13 PM9/26/22
to
Am 26.09.2022 um 14:18 schrieb Paavo Helde:

> Except when there is (a problem). You do not need a dependency on a
> global object, just calling a function using the non-constructed global
> object is enough.

That's also not a problem because when you call that function the
dependent object is already created just by loading the libary.

Rest unread.


Andrey Tarasevich

unread,
Sep 26, 2022, 10:58:14 PM9/26/22
to
"Indeterminate"? Well, no, the language specification does not simply
shrug it off as "indeterminate".

The entire [basic.start.static] and [basic.start.dynamic] are dedicated
to describing the intricate details of what orderings exist and what
don't in initialization of non-local objects. That includes unordered,
partially-ordered and ordered initialization sequences.

--
Best regards,
Andrey





Paavo Helde

unread,
Sep 27, 2022, 2:48:41 AM9/27/22
to
From what I'm reading there, such initialization order problems can be
solved by C++ modules support. The import declarations define an acyclic
graph of modules, and the non-local variables of a dependency are
guaranteed to be dynamically initialized before those of the dependant
module (at least when this happens after entering main(), which is the
case for me).

0 new messages