15

In 29.5 Atomic types of the C++ Standard November 2014 working draft it states:

  1. There is a generic class template atomic. The type of the template argument T shall be trivially copyable (3.9). [ Note: Type arguments that are not also statically initializable may be difficult to use. —end note ]

So - as far as I can tell - this:

#include <atomic>

struct Message {
    unsigned long int a;
    unsigned long int b;
};

std::atomic<Message> sharedState;

int main() {    
    Message tmp{1,2};       
    sharedState.store(tmp);         
    Message tmp2=sharedState.load();
}

should be perfectly valid standard c++14 (and also c++11) code. However, if I don't link libatomic manually, the command

g++ -std=c++14 <filename>

gives - at least on Fedora 22 (gcc 5.1) - the following linking error:

/tmp/ccdiWWQi.o: In function `std::atomic<Message>::store(Message, std::memory_order)':
main.cpp:(.text._ZNSt6atomicI7MessageE5storeES0_St12memory_order[_ZNSt6atomicI7MessageE5storeES0_St12memory_order]+0x3f): undefined reference to `__atomic_store_16'
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::load(std::memory_order) const':
main.cpp:(.text._ZNKSt6atomicI7MessageE4loadESt12memory_order[_ZNKSt6atomicI7MessageE4loadESt12memory_order]+0x1c): undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status

If I write

g++ -std=c++14 -latomic <filename>

everything is fine. I know that the standard doesn't say anything about compiler flags or libraries that have to be included, but so far I thought that any standard conformant, single file code can be compiled via the first command.

So why doesn't that apply to my example code? Is there a rational why -latomic is still necessary, or is it just something that hasn't been addressed by the compiler maintainers, yet?

MikeMB
  • 20,029
  • 9
  • 57
  • 102

3 Answers3

6

Relevant reading on the GCC homepage on how and why GCC makes library calls in certain cases regarding <atomic> in the first place.

GCC and libstdc++ are only losely coupled. libatomic is the domain of the library, not the compiler -- and you can use GCC with a different library (which might provide the necessary definitions for <atomic> in its main proper, or under a different name), so GCC cannot just assume -latomic.

Also:

GCC 4.7 does not include a library implementation as the API has not been firmly established.

The same page claims that GCC 4.8 shall provide such a library implementation, but plans are the first victims of war. I'd guess the reason for -latomic still being necessary can be found in that vicinity.

Besides...

...so far I thought that any standard conformant, single file code can be compiled via the first command.

...-lm has been around for quite some time if you're using math functions.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • 2
    Note that the C++ Standard is somewhat ambiguous whether the library is a separate component - the library sections are fairly standalone, but "the implementation" in standardese means the combination of compiler and library. – MSalters Jun 02 '15 at 09:44
  • 1
    Correct me if I'm wrong, but gcc DOES - by default - include a couple of libraries, so how would a default `-latomic` be different? – MikeMB Jun 02 '15 at 10:18
  • @MSalters: Yes, but in the case of GCC, "the implementation" means "GCC and some compatible standard library". That's what I wanted to point at -- a not-yet-finalized API between the compiler and *one* of its (n) standard libraries, and you get a separate `-latomic` from the compiler people that didn't think it all that problematic to require a `-lm` for math code either. No big deal, all around. – DevSolar Jun 02 '15 at 10:42
  • 1
    I haven't used gcc in a long while, but for g++ -lm isn't necessary is it? – MikeMB Jun 02 '15 at 11:14
  • Btw: Your Quote about gcc 4.7 was the reason I was asking, why it's STILL necessary in GCC 5.1. – MikeMB Jun 02 '15 at 11:23
  • @MikeMB: Can't really say (with regards to `-lm`) because I haven't used `` in a long while. ;-) – DevSolar Jun 02 '15 at 11:55
  • @MikeMB: I'm using GCC both as a native compiler and as a cross-compiler for multiple arm-linux platforms (hard and soft FP). In none of those, I need an `-lm` with `g++`, and my code is math-heavy enough to warrant a `-fpmath=sse`. – MSalters Jun 02 '15 at 12:04
  • The comparison with `-lm` is really wrong. libm is provided by libc (at least on most *nix platforms), and so is meaningful for most of the compilers. libatomic is an internal gcc library that is needed on some arches for some cases of atomics, for some gcc versions (and clang with -rtlib=libgcc). In other words, adding `-lm` is usually safe, adding `-latomic` is pretty much a guesswork. – Michał Górny Feb 17 '17 at 07:57
1

I know that the standard doesn't say anything about compiler flags or libraries that have to be included

Right.

but so far I thought that any standard conformant, single file code can be compiled via the first command.

Well, no. As you just said, there is no particular reason to assume this. Consider also that GCC extensions are enabled by default.

That being said, it seems self-evident that the intention is to make -latomic a default part of the runtime when it's settled down a bit.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Obviously I didn't make that assumption based on anything written in the standard, but based on my(somewhat limited) experience with g++. Also correct me if I'm wrong, but doesn't `-std=c++11` disable g++ specific extensions? – MikeMB Jun 02 '15 at 10:39
  • @MikeMB: Oh, it might. – Lightness Races in Orbit Jun 02 '15 at 10:46
  • Continuing to require `-latomic` explicitly is a good way to detect use of non-lock-free atomics, on platforms where lock-free atomics can inline. (Sometimes this requires `-march=native` or something else to enable an ISA extension, or for ARM a `-mcpu=` setting to enable it.) – Peter Cordes Sep 11 '22 at 04:14
-3

g++ is a wrapper for gcc which adds the correct C++ libraries. Clearly -latomic is missing from that list. Not a core compiler problem then, simply a minor bug in the wrapper.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • It might well be a conscious decision as it is not fully implemented yet. In particular *29.3 Order and consistency* support is listed as Partial. https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2014 – Captain Giraffe Jun 02 '15 at 09:26
  • 6
    `g++` is _not_ "a wrapper for `gcc`". They're more like siblings, both wrapping the various actual compilers (e.g. `cc1plus`). – Lightness Races in Orbit Jun 02 '15 at 09:40