lua-users home
lua-l archive

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

I disagree. In practice the linker are trying to resolve symbols by starting from a first unit and using the other modules and libraries one by one, in the strict order where they are specified in the link command, until there remains no other unresolved symbols, at which time all other units may be discarded, when building a standalone application, or still added to the pack when building a library. But the linker will emit a warning if it finds a symbol redefined by another unit, because the result of the link can only keep one of the reference, the first one encountered, the rest, if it is not reachable at all by any other exported symbol part of the smallest unit, can be discarded directly by the linker.

So the order by which you specify the compiled units, and then the libraries, is significant.

E.g a link command specifying "-ll -lm" is not equivalent to the same command specifying "-lm -ll" instead. The same remark applies to the ordered list of .o units, which just come as a first group before all libraries, but are not necessarily all included in the linker module, except when building a library and the modules kept in the library still have at least one distinctive symbol.

Le mer. 21 nov. 2018 à 13:45, Viacheslav Usov <> a écrit :
On Wed, Nov 21, 2018 at 12:12 PM Luiz Henrique de Figueiredo <> wrote:

> The C standard is talking about the definition of symbols but it never mentions a linker or how it should work, AFAIR.

This is not true. For example, in C89, clause Translation phases, number 8:

All external object and function references are resolved. Library components are linked to satisfy external references to functions and objects not defined in the current translation. 


This is echoed verbatim in C11. The requirements for external references and definitions are covered elsewhere in the standard (I cited them earlier).

> The linker is just implementing the requirements in the C standard in a reasonable and convenient way:

The linker is either conformant or not. However, the particular requirement of "one definition only" is one where the standard lets the implementation (i.e., the linker) behave in an undefined way (because the standard implicitly recognises that an implementation may not have sufficient means to enforce conformant behaviour). This merely means that the onus is on the programmer to ensure that the whole program is conformant, which, in this case, means to ensure that no function is defined more than once in the program, which includes all its libraries.

> A library is not meant to be totally incorporated into the program; only modules that provide definitions for the program are incorporated.

This is, in fact, not a requirement. An implementation is free to incorporate all of the library. And when a shared library used, this is exactly what happens.

If the previous "static" linking phase has resolved some of the dependencies, these dependencies won't be resolved during the "dynamic" linking phase to the functions incorporated in the shared library. This is permitted under the broad umbrella of undefined behaviour. However, this:

> Again, this is reasonable and convenient, and works extremely well in practice. It has been like that for many decades.

would be a dangerous idea to entertain.

First, other libraries that the executable depends on will not have been linked statically to the same "replacement" functions, so they will have to resort to the "original" dependencies. Your program, as whole, may end up using different versions of the same set of functions simultaneously. Even without those other libraries the sole library that you intend to patch "without patching" can happily continue using its own functions, with the same result.

Second, if those other libraries resort to the same trick, the situation is not just proportionally worse, it is much worse because this may end up with duplicate export symbols and a whole new problem to solve.

Finally, none of this is portable and on some platforms one would have to go through pretty serious gyrations to convince the linker it is OK to have duplicate symbols and that these particular ones are to be used statically. Which is actually good.