On Thu, 6 Apr 2023 at 05:04, Steve Thompson via Gcc-help <gcc-help@xxxxxxxxxxx> wrote: > > I have a perplexing problem in compiling source files: > > make[1]: Leaving directory '/home/stevet/stuff/src/projects/olock-beta/arch' > ar cr libolock.a anon_pages.o aobm.o apool.o asm_ops.o bool.o debugging.o > microsecond_time.o nanosecond_time.o obm.o olock.o os_linux.o platform.o > posix_mmap.o posix_threads.o statistics.o > ranlib libolock.a > make -C test > make[1]: Entering directory > '/home/stevet/stuff/src/projects/olock-beta/test' > gcc10.4 -D _DEFAULT_SOURCE -DARCH_64 -DOLOCK_192 -DLINUX -I./ -I../ > -pthread -m64 -std=c99 -Wall -Wextra -Werror -fdiagnostics-color=never -O > -ggdb -DUSE_OBM -o otest otest.c ../libolock.a > /usr/bin/ld: ../libolock.a(debugging.o): in function `apool_init_freelist': > /home/stevet/stuff/src/projects/olock-beta/./apool.h:92: multiple > definition of `apool_init_freelist'; > /tmp/ccZflz99.o:/home/stevet/stuff/src/projects/olock-beta/test/../apool.h:92: > first defined here > /usr/bin/ld: ../libolock.a(olock.o): in function `apool_init_freelist': > /home/stevet/stuff/src/projects/olock-beta/./apool.h:92: multiple > definition of `apool_init_freelist'; > /tmp/ccZflz99.o:/home/stevet/stuff/src/projects/olock-beta/test/../apool.h:92: > first defined here > /usr/bin/ld: ../libolock.a(platform.o): in function `apool_init_freelist': > /home/stevet/stuff/src/projects/olock-beta/./apool.h:92: multiple > definition of `apool_init_freelist'; > /tmp/ccZflz99.o:/home/stevet/stuff/src/projects/olock-beta/test/../apool.h:92: > first defined here > /usr/bin/ld: ../libolock.a(posix_threads.o): in function > `apool_init_freelist': > /home/stevet/stuff/src/projects/olock-beta/./apool.h:92: multiple > definition of `apool_init_freelist'; > /tmp/ccZflz99.o:/home/stevet/stuff/src/projects/olock-beta/test/../apool.h:92: > first defined here > /usr/bin/ld: ../libolock.a(anon_pages.o): in function `apool_init_freelist': > /home/stevet/stuff/src/projects/olock-beta/./apool.h:92: multiple > definition of `apool_init_freelist'; > /tmp/ccZflz99.o:/home/stevet/stuff/src/projects/olock-beta/test/../apool.h:92: > first defined here > /usr/bin/ld: ../libolock.a(os_linux.o): in function `apool_init_freelist': > /home/stevet/stuff/src/projects/olock-beta/./apool.h:92: multiple > definition of `apool_init_freelist'; > /tmp/ccZflz99.o:/home/stevet/stuff/src/projects/olock-beta/test/../apool.h:92: > first defined here > collect2: error: ld returned 1 exit status > make[1]: *** [Makefile:31: otest] Error 1 > make[1]: Leaving directory '/home/stevet/stuff/src/projects/olock-beta/test' > make: *** [Makefile:36: test] Error 2 > > Actually there are two problems, and I had to do something stupid to get > this error, so that one first. > > All of the .h files are referenced in a particular sequence in platform.h > and each source module compiled above only includes the consolidated header. > > In microsecond_time.h there are several definitions, one of which is > "typedef s64 T64;". Now the T64 type is used all over the place and is > defined correctly _except_ for microsecond_time.h. When > microsecond_time.c is compiled the typedef is missing from the --save-temps > file, whereas it is present in all of the other compilation units. To That suggests either the typedef is guarded by some #if check, or that compilation unit defines either s64 or T64 as a macro. But nobody can tell you what you've done wrong when only you can see the code. If you're looking at the save-temps output you should be able to figure it out - everything you need to know is shown there, or in the output of gcc -E -dD which shows all the macro definitions as well. > fudge it I modified microsecond_time.c to include only the necessary > headers and added a redundant "typedef s64 T64" line in microsecond_time.c > -- and it compiles! > > The second problem is shaped as follows: apool_init_freelist() is defined > in apool.h as __inline__ and is referenced by two more __inline__ macros, > like this: You haven't said what the __inline__ macro is defined as, or why you're using it instead of the standard C99 inline keyword. Maybe https://gcc.gnu.org/gcc-5/porting_to.html#inline is relevant for you. > > __inline__ void apool_init_freelist(apool * a) { > a->free_list = 1; > apool_fl_nr_cells(a, 1) = a->pool.nr_cells - 1; // macro > apool_fl_next(a, 1) = 0; // macro > a->nr_free = a->pool.nr_cells - 1; > } > > ... > __inline__ void init_apool_struct(apool * p) > { > p->nr_free = p->pool.nr_cells - 1; > p->pool.offset = sizeof(apool); > apool_init_freelist(p); > } > > These functions aren't used anywhere yet so no code whatsoever should be > generated for apool_init_freelist(). And yet, as you can see in the > linker errors, several modules that do not reference those functions at all > have a symbol and code for the "inline" function. > > In comp.lang.c (and in 2018) there is a thread that discusses an eerily > similar problem but in that case it seems to be triggered by a "#define > __attribute__(x)" before inclusion of normal libc headers (affecting atoi) > : (damn google) > > https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwiP--P5qpT-AhVjADQIHSMZBmQQFnoECAkQAQ&url=https%3A%2F%2Fgroups.google.com%2Fg%2Fcomp.lang.c%2Fc%2F0fqzRqf--ds&usg=AOvVaw3gu9TODPn58URUag7Y6B5d > > The followups do not reveal a cause; the original poster found a workaround > that doesn't apply to my situation. I could in theory work around this > problem by changing all the __inline__ (in .h files) functions to macros, > or by moving all the inline functions to the .c files, but the whole point > of the "apool" abstraction is that it is a very thin layer and should be > inline. If I change all the header inline functions to macros it begs the > reason for having __inline__ at all. > > At any rate both of these problems are entirely mysterious to me. I can't > see a reason gcc would produce static copies of a function that is never > used in some but not all source modules where it is defined. And second, I > should be getting an error for a redefined typedef as things stand with > microsecond time.c. > > One last thing, if I compile with -O0 a whole slew of functions declared > "inline" are silently deleted and show up as missing symbols in the static > library link. > > I am at a loss. Suggestions for what to look for would be appreciated.