Hide Forgot
Description of problem: Whet you build nunc-stans with gcc5, the output of readelf -Ws shows: Num: Value Size Type Bind Vis Ndx Name 107: 0000000000005c50 52 FUNC GLOBAL DEFAULT 11 abstraction_increment When you build this with gcc6, you receive: Num: Value Size Type Bind Vis Ndx Name 13: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND abstraction_increment When you then compile another application and attempt to link to nunc-stans, this fails with: ../nunc-stans-0.1.7/lib/libnunc-stans.so: undefined reference to `abstraction_increment' The definition of abstraction_increment is: INLINE atom_t abstraction_increment( atom_t *value ) Where INLINE is a macro to: #define INLINE extern __forceinline There are a number of other functions in nunc-stans that use our INLINE macro. For example: INLINE atom_t abstraction_cas( volatile atom_t *destination, atom_t exchange, atom_t compare ) In both gcc5 and 6 this works correctly: 5 Num: Value Size Type Bind Vis Ndx Name 64: 0000000000005ba0 162 FUNC GLOBAL DEFAULT 11 abstraction_dcas 6 Num: Value Size Type Bind Vis Ndx Name 65: 0000000000005cc0 162 FUNC GLOBAL DEFAULT 12 abstraction_dcas Version-Release number of selected component (if applicable): gcc-6.0.0-0.9.fc24.x86_64 How reproducible: Always. This always and only affects abstraction_increment in this code base. Steps to Reproduce: 1. Build the 389-ds rpm that includes nunc-stans Actual results: Build fails. Expected results: Build succeeds. Additional info: Happy to help providing any information as required to solve this.
This is a flaw in the library. Please read something about GNU89 inline vs. C99 inline, GCC these days defaults to C11 and therefore the C99 inline semantics is used by default. INLINE doesn't expand to extern __forceinline as you wrote, but just to inline. And in C99, that means that the function may be inlined, but an external symbol is not emitted. You'd need extern inline for that purpose. Though of course, it is questional why do you use in a translation unit that contains just that function an INLINE at all, there is nothing to inline it into. If you want to support still older GCC versions and/or building with -std=gnu89, where the GNU89 inline semantics is present, you might want to do something like #ifdef __GNUC_STDC_INLINE__ #define INLINE extern inline #else #define INLINE inline #endif in the GCC header snippets. That of course assumes you only use INLINE in the GNU89 inline or C99 extern inline way, not e.g. static INLINE etc.