Bug 81358 - libatomic not automatically linked with C11 code
Summary: libatomic not automatically linked with C11 code
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: driver (show other bugs)
Version: 7.1.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: link-failure
Depends on:
Blocks:
 
Reported: 2017-07-08 11:01 UTC by Francois-Xavier Coudert
Modified: 2017-08-20 11:23 UTC (History)
3 users (show)

See Also:
Host: x86_64-apple-darwin16.5.0
Target: x86_64-apple-darwin16.5.0
Build: x86_64-apple-darwin16.5.0
Known to work:
Known to fail:
Last reconfirmed: 2017-07-08 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Francois-Xavier Coudert 2017-07-08 11:01:44 UTC
This is on macOS 10.12 (Darwin 16.6.0). Compiling C11 code with -std=c11 fails to link, unless one specifies -latomic

$ cat a.c
#include <stdio.h>
#include <complex.h>
#include <stdatomic.h>

int main(void)
{
    _Atomic long double _Complex x = 0.0 + 0.0*I;
    for (int i=0; i<1000; i++) {
        x += 1.0;
    }
    printf("(%Lf,%Lf)\n",creall(x), cimagl(x));
    printf("%zu\n",sizeof(x));
    return 0;
}

$ gcc-7 -std=c11 a.c -latomic
$ gcc-7 -std=c11 a.c         
Undefined symbols for architecture x86_64:
  "___atomic_feraiseexcept", referenced from:
      _main in cceeEpua.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status


------

From Homebrew report at https://github.com/Homebrew/homebrew-core/issues/14633

$ gcc-7 -v
Using built-in specs.
COLLECT_GCC=gcc-7
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/7.1.0/libexec/gcc/x86_64-apple-darwin16.6.0/7.1.0/lto-wrapper
Target: x86_64-apple-darwin16.6.0
Configured with: ../configure --build=x86_64-apple-darwin16.6.0 --prefix=/usr/local/Cellar/gcc/7.1.0 --libdir=/usr/local/Cellar/gcc/7.1.0/lib/gcc/7 --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-7 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --enable-checking=release --with-pkgversion='Homebrew GCC 7.1.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-nls --with-native-system-header-dir=/usr/include --with-sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk
Thread model: posix
gcc version 7.1.0 (Homebrew GCC 7.1.0)
Comment 1 Marc Glisse 2017-07-09 01:45:59 UTC
That seems similar to using sqrt, which requires explicitly linking with libm.
Comment 2 Andreas Schwab 2017-07-09 05:43:51 UTC
That doesn't mean that the mistake should be repeated.
Comment 3 joseph@codesourcery.com 2017-07-10 17:01:14 UTC
See what I said in 
<https://gcc.gnu.org/ml/gcc-patches/2013-11/msg02605.html> - I think 
linking --as-needed -latomic --no-as-needed makes sense by default when 
--as-needed is supported.  The problem would be any platforms where (a) 
there is no --as-needed support, but (b) shared libraries are supported 
and linking with a shared library introduces a dependency into the binary 
even if no symbols from that shared library are used.
Comment 4 joseph@codesourcery.com 2017-07-10 17:02:49 UTC
In the libm case, POSIX has an explicit list of headers whose functions 
may require particular libraries to be linked in.  libatomic is required 
for use of language features without any reference to functions from any 
header.
Comment 5 Jeff Hammond 2017-07-10 17:56:18 UTC
Indeed, _Atomic is a language keyword and doesn't require any headers (the inclusion of stdatomic.h in this code is superfluous), so the "header->explicit library" argument doesn't apply.

In any case, I do not see why language intrinsics that require headers should require libraries.  Why is sqrt() from math.h different from fprintf() from stdio.h?  Maybe POSIX requires that, but ISO C11 doesn't, and I'm using -std=c11 not -std=posix.

--as-needed would greatly enhance user experience for both this and libm.
Comment 6 joseph@codesourcery.com 2017-07-10 20:02:24 UTC
The design of what's in separate libraries is historical; since it 
probably predates shared libraries, the reason isn't obvious (with shared 
libraries, before --as-needed, it avoided unnecessary runtime 
dependencies).  The conformance documentation for an implementation as a 
whole (compiler plus libraries) would of course specify using -std=c11 
-pedantic -lm -latomic, or whatever.  For a new libc implementation for 
Unix-like systems it would be natural just to use libc.so for everything, 
subject to performance issues from causing everything to be (potentially) 
multithreaded by linking with pthreads functions.  Note e.g. glibc moved 
some clock/timer functions from librt to libc a while back to avoid such 
issues from linking in librt.

The POSIX rules for the c99 utility, which correspond more or less to the 
traditional division into libraries on Unix-like systems, are at: 
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/c99.html