oarfish
oarfish

Reputation: 4631

Why does this C++ program compile on MacOS but not Ubuntu?

I am using Clang version 10 on Ubuntu and MacOS machines:

ubuntu $ clang++ --version
clang version 10.0.0-++20200227124856+593a0dda7a6-1~exp1~20200227115450.103
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
osx $ clang++ --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

The following simple program does not compile on Ubuntu (16.04), but does on MacOS 10.14:

// test.cpp

#include <atomic>
struct foo {

  bool bar;
  int baz;
  foo(bool bar, int baz) : bar(bar), baz(baz) {
  }
};

int main(int argc, char* argv[]) {
  std::atomic<foo> test_struct({false, 0});
  test_struct.load();

  return 0;
}

I am compiling with

clang++ -std=c++14 test.cpp -o test

The error on Ubuntu is

In file included from test.cpp:1:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/atomic:234:13: error: no matching constructor for initialization of 'foo'
        _Tp tmp;
            ^
test.cpp:13:11: note: in instantiation of member function 'std::atomic<foo>::load' requested here
  test_struct.load();
          ^
test.cpp:2:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
struct foo {
       ^
test.cpp:2:8: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
test.cpp:6:3: note: candidate constructor not viable: requires 2 arguments, but 0 were provided
  foo(bool bar, bool baz) :
  ^
1 error generated.

Am I running into some undefined behaviour here? Or what measures do I need to take to make the two scenarios completely equal?

Edit I can make this compile by adding a default constructor to the type. However I cannot parse this requirement from std::atomics documentation and I am confused why the default constructor appears to be generated on MacOS but not on Ubuntu.

Upvotes: 2

Views: 639

Answers (1)

oarfish
oarfish

Reputation: 4631

The answer is that on Linux systems, clang links against the GNU C++ standard library implementation libstc++, which in this case is too old (version 5.4. or some such) and does not work with the language standard selected (c++14).

There are two solutions:

  1. Somehow install an updated libstdc++, which may or may not be in the APT package repositories for the Ubuntu version (in my case there is no newer version)
  2. Make clang use the LLVM implementation libc++. Make sure there is a recent version installed (package libc++-dev) and pass -stdlib=libc++ during compilation.

Upvotes: 2

Related Questions