Does clang on Mac not support uniform initialization? - c++

Is clang on Mac not support uniform initialization?
I tried compiling following code, But compiler raise a error.
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<int> v = {3, 1, 9, 4};
std::cout << v[1] << std::endl;
}
Error:
vector.cpp:9:22: error: non-aggregate type 'std::vector<int>' cannot be initialized with an initializer list
std::vector<int> v = {3, 1, 9, 4};
^ ~~~~~~~~~~~~
1 error generated.
OS: macOS 10.12.4
compiler version:
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

I suspect you are not compiling the code as C++11/14 (-std=c++11 or -std=c++14)? If not; do that. Clang does support what you are trying to do.

Related

Apple's clang can't use <=> with std::tuple

The following compiles fine with GCC and clang on on godbolt, but on my MacBook, in Xcode 14 it dies:
#include <iostream>
#include <compare>
#include <tuple>
using std::cout; using std::tuple; using std::endl;
int main() {
tuple<float, float> tuplee = {1.0,2.0};
tuple<float, float> tuploo = {3.0,4.0};
cout << (tuplee < tuploo) << endl;
auto res = (tuplee <=> tuploo);
cout << (res < 0) << endl;
return 0;
}
The error is:
invalid operands to binary expression ('std::tuple<float, float>' and 'std::tuple<float, float>')
It points to the <=> on the tuples. Do you think it's a bug in Apple's clang, or am I missing something?
Command line on my MacBook:
% clang++ --version
Apple clang version 14.0.0 (clang-1400.0.29.102)
Target: x86_64-apple-darwin22.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
% clang++ -std=c++2b main.cpp
main.cpp:11:21: error: invalid operands to binary expression ('tuple<float, float>' and 'tuple<float, float>')
cout << (tuplee <=> tuploo) << endl;
~~~~~~ ^ ~~~~~~
1 error generated.
I think it is a bug. The bug was fixed in llvm (relevant change). But by checking the tuple header in Macos SDK, one can find apple do not implement <=> for tuple.
The bug also affects arm64 variants of Macos. Clang version on my mac:
➜ test clang --version
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
PS. Homebrew llvm#14 compiles fine. Just do not use apple clang

C++ compiler throws error on dynamic array with default values

Mac g++ throws a compilation error with this code:
#include <iostream>
using namespace std;
int main(int argc, char ** argv) {
int * p = new int[5] {1,2,3};
return 0;
}
I tried an online compiler and it compiles and runs without errors.
Is there something wrong with mac compiler? Can I do something to change how it works or should I install another c++ compiler?
Edit:
The error:
test.cpp:6:25: error: expected ';' at end of declaration
int * p = new int[5] {1,2,3};
Compiler target and version:
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Compile command:
g++ test.cpp
There's no fundamental reason not to allow a more complicated initializer it's just that C++03 didn't have a grammar construct for it. In the next version of C++, you will be able to do something like this.
int* p = new int[5] {0, 1, 2, 3, 4};
You can try adding -std=c++11 to your command line and that should be working all fine.

Why I can't include some headers from C++17 on mac

My system: macOS Catalina(10.15.4)
Brew config
Clang: 11.0 build 1103
Git: 2.21.0 => /usr/local/bin/git
Curl: 7.64.1 => /usr/bin/curl
Java: 1.8.0_101
macOS: 10.15.4-x86_64
CLT: 11.4.1.0.1.1586360307
Xcode: N/A
Issue: can't include some C++17 headers: execution, filesystem
while can include the other like: any, variant.
Most of C++17 features like structured binding, template parameters deduction etc works.
Example. Trying to build a file with the following code snippet:
#include <numeric>
#include <vector>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <utility> //std::pair
#include <tuple> // std::tie
#include <algorithm> // std::clamp
#include <optional> // std::optional
#include <map>
// ... other stuff
#include <execution>
namespace parallel_algoritmhs {
void show() {
std::vector<int> v = {1,2,3,4,5,6};
std::for_each(std::execution::par, v.begin(), v.end(), [](auto& e) {e+=100;});
int main() {
//... use
}
I am building with:
g++ -std=c++17 -fsanitize=undefined -fno-sanitize-recover=all -o main c++17.cpp
Update:
I have tried suggested:
clang -std=c++17 -fsanitize=undefined -fno-sanitize-recover=all -o main c++17.cpp
clang++ -std=c++17 -fsanitize=undefined -fno-sanitize-recover=all -o main c++17.cpp
And getting the same result.
If I comment out code snippet related to different execution strategies, while leaving other code snippets like:
#include <any>
namespace any {
void show() {
std::any v = 42;
v = 4.2;
v = std::string{"hello"};
std::cout << std::any_cast<std::string>(v) << '\n';
}
}
namespace map_cpp17 {
void show() {
std::map<int, std::string> myMap{ { 1, "Gennady" }, { 2, "Petr" }, { 3, "Makoto" } };
auto node = myMap.extract(2);
node.key() = 42;
myMap.insert(std::move(node));
std::map<int, std::string> m1{ { 1, "aa" }, { 2, "bb" }, { 3, "cc" } };
std::map<int, std::string> m2{ { 4, "dd" }, { 5, "ee" }, { 6, "ff" } };
m1.merge(m2);
std::map<int, std::string> m; m.emplace(1, "aaa"); m.emplace(2, "bbb"); m.emplace(3, "ccc");
auto [it1, inserted1] = m.insert_or_assign(3, "ddd"); std::cout << inserted1; // 0
auto [it2, inserted2] = m.insert_or_assign(4, "eee"); std::cout << inserted2; // 1
}
}
Everything compiles
With
#include <execution>
getting:
fatal error: 'execution' file not found
#include <execution>
I wonder what might be the problem behind that and how to fix this.
Thank you!
Update 2:
brew info llvm:
llvm: stable 10.0.0 (bottled), HEAD [keg-only]
Next-gen compiler infrastructure
https://llvm.org/
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/llvm.rb
==> Dependencies
Build: cmake ✔, python#3.8 ✘
Required: libffi ✘
==> Requirements
Build: xcode ✘
==> Options
--HEAD
Install HEAD version
==> Caveats
To use the bundled libc++ please add the following LDFLAGS:
LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
llvm is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
Update 3:
clang --version
Apple clang version 11.0.3 (clang-1103.0.32.59)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
You're not actually using the Clang you installed. The official LLVM Clang doesn't have a version 11.0! LLVM is only on version 10.0 (check brew info llvm). You're using Apple Clang, which comes with its own installation of libc++. Presumably to catch this exact type of problem, Apple Clang responds to clang --version/clang++ --version with the "future" version 11.0. However, Apple's distribution is actually a bit behind the state of the art, and it simply isn't updated to these features.
When you install LLVM with Homebrew, it doesn't automatically set it up the new clang/clang++ to be easily callable, because things might expect clang to specifically mean "Apple Clang" and break if that changes. You should add /usr/local/opt/llvm/bin (which Homebrew symlinks into the LLVM installation) to your PATH (which is where your shell and other programs search for programs). In an already running shell session
export PATH="/usr/local/opt/llvm/bin:$PATH"
will switch to using the newly installed LLVM Clang until you exit the session. Putting this line in a shell startup file, like ~/.bash_profile, will set up this adjustment to be applied every time you open a new shell.
Alternatively, like #Eljay does, you could just manually type out the full path to the new clang/clang++ (/usr/local/opt/llvm/bin/clang/-++), thereby bypassing the search into PATH, but that's a pain. In any case, you'll know you got it right if clang --version/clang++ --version gives you 10.0.0.

Can't compile C++ 17 structured bindings

The following code
#include <iostream>
#include <tuple>
int main()
{
auto [i, c, d] = std::make_tuple(1, 'a', 2.3);
std::cout << "i=" << i << " c=" << c << " d=" << d << '\n';
return 0;
}
doesn't get compiled on my computer. I get these error messages:
error: use of undeclared identifier 'i'
error: expected unqualified-id
and some more of the same type.
I'm using: Mac OS X 10.11.6 El Capitan, CLion. I did choose the C++ 17 option when I created the project and my CMakeList.txt has this line:set(CMAKE_CXX_STANDARD 17).
clang --version - Apple LLVM version 8.0.0 (clang-800.0.42.1)
What do I need to do to compile this code?
As #Eljay said in the comments, older versions of clang did (do) not have complete C++17 support.
I have reproduced this issue w/o CLion.
On a 10.11.6 machine, using "Apple LLVM version 8.0.0 (clang-800.0.42.1)"
clang++ -std=c++1z junk.cpp
gives the errors that the OP reported. (Note that -std=c++17 is not a valid option here - that came later)
On a 10.14.2 machine, using "Apple LLVM version 10.0.0 (clang-1000.10.44.4)"
clang++ -std=c++17 junk.cpp
compiles w/o error.

MinGW GCC 4.8.0 on Windows doesn't support atomic features

#include <atomic>
struct SomeType
{
int a;
int b;
int c;
int d;
};
int main()
{
SomeType s1 = {1, 2, 3, 4};
std::atomic<SomeType> s2(s1);
SomeType s3 = s2.load();
return 0;
}
The code doesn't link using gcc version 4.8.0 (rev2, Built by MinGW-builds project) with gcc -std=c++11 t.cpp. Error messages are:
ccGPZTVk.o:t.cpp(.text$_ZNKSt6atomicI8SomeTypeE4loadESt12memory_order[__ZNKSt6atomicI8SomeTypeE4loadESt12memory_order]+0x21): undefined reference to `__atomic_load_16'
collect2.exe: error: ld returned 1 exit status
According to C++11 standard, types like SomeType which is trivially copyable should definitely fit in a std::atomic...and MSVC cl /EHsc t.cpp works like a charm. Is this a bug of GCC? How can I solve this weird problem...