Почему я не могу включить некоторые заголовки из C ++ 17 на Mac - PullRequest
0 голосов
/ 30 апреля 2020

Моя система: macOS Catalina (10.15.4)

Настройка Brew
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

Проблема: не может включать некоторые заголовки C ++ 17: выполнение , файловая система
, в то время как может включать другое, например: любой , вариант .
Большинство функций C ++ 17, таких как структурированное связывание, вычитание параметров шаблона эт c работает.

Пример. Попытка создать файл со следующим фрагментом кода:

#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 
}

Я строю с:

g++ -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
clang++ -std=c++17 -fsanitize=undefined -fno-sanitize-recover=all -o main c++17.cpp

И получить тот же результат.

Если я закомментирую фрагмент кода, связанный с различными стратегиями выполнения, оставляя другие фрагменты кода, такие как:

#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
  }
}

Все компилируется

С

#include <execution>

получая:

fatal error: 'execution' file not found  
#include <execution>

Интересно, в чем может быть проблема и как это исправить. Спасибо!

Обновление 2: информация о пиве 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.

Обновление 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

1 Ответ

1 голос
/ 30 апреля 2020

Вы на самом деле не используете установленный Clang. Официальный LLVM Clang не имеет версию 11.0! LLVM только на версии 10.0 (отметьте brew info llvm). Вы используете Apple Clang, который поставляется с собственной установкой libc ++. Предположительно, чтобы уловить этот тип проблемы, Apple Clang отвечает на clang --version / clang++ --version «будущей» версией 11.0. Однако дистрибутив Apple на самом деле немного отстает от уровня техники, и он просто не обновляется до этих функций.

Когда вы устанавливаете LLVM с Homebrew, он не устанавливает автоматически новый clang / clang++ легко вызывается, потому что можно ожидать, что clang будет означать "Apple Clang" и сломаться, если это изменится. Вы должны добавить /usr/local/opt/llvm/bin (какие символические ссылки Homebrew в установку LLVM) в PATH (где ваша оболочка и другие программы ищут программы). В уже запущенном сеансе оболочки

export PATH="/usr/local/opt/llvm/bin:$PATH"

будет переключаться на использование только что установленного LLVM Clang, пока вы не выйдете из сеанса. Если поместить эту строку в файл запуска оболочки, например ~/.bash_profile, эта настройка будет применяться при каждом открытии новой оболочки.

В качестве альтернативы, как это делает @Eljay, вы можете просто набрать вручную полный путь к новому clang / clang++ (/usr/local/opt/llvm/bin/clang / - ++), тем самым обходя поиск в PATH, но это боль. В любом случае вы узнаете, что все правильно, если clang --version / clang++ --version даст вам 10.0.0.

...