Я только что купил книгу Beginning C++20 (версия для электронных книг) и пытаюсь скомпилировать первый пример, используя новый метод C++20.
Содержимое исходного файла
// Ex1_01.cpp
// A Complete C++ program
import <iostream>;
int main()
{
int answer{42}; // Defines answer with 42
std::cout << "The answer to life, the universe, and everything is "
<< answer
<< std::endl;
return 0;
}
Если я правильно понимаю, это еще не поддерживается GCC версии 10 или 11 (некоторые сайты утверждают, что GCC 11 поддерживает это, но когда я использую флаг -fmodules-ts, как некоторые предполагают, появляется сообщение об ошибке, что он не реализован/экспериментальный и уходит.
После некоторого поиска я нашел несколько сообщений со ссылкой на https://gcc.gnu.org/wiki/cxx-modules, где есть инструкции по установке версии GCC 10 с поддержкой модулей (используя -fmodules- ts), но когда я использую это в своем примере кода, я получаю следующую ошибку:
In module imported at Ex1_01.cpp:3:1:
/usr/local/include/c++/10.0.0/iostream: error: failed to read compiled module: No such file or directory
/usr/local/include/c++/10.0.0/iostream: note: compiled module file is ‘gcm.cache/./usr/local/include/c++/10.0.0/iostream.gcm’
/usr/local/include/c++/10.0.0/iostream: fatal error: jumping off the crazy train to crashville
compilation terminated.
Версия gcc: g++ (GCC) 10.0.0 20200110 (экспериментальная версия) [svn-280157:20201220-1704] Я нашел сообщение здесь, в Stack Overflow, где кто-то указывает на эту версию (Как скомпилировать код C++ с использованием modules-ts и gcc (экспериментально)?)
Я также попробовал примеры из вики (hello.cc и main.cc), но они также выдают сообщение об ошибке:
In module imported at main.cpp:1:1:
hello: error: failed to read compiled module: No such file or directory
hello: note: compiled module file is ‘gcm.cache/hello.gcm’
hello: fatal error: jumping off the crazy train to crashville
compilation terminated.
Есть ли способ заставить это работать, или я должен просто начать со «старого» метода #include, пока не появится стабильная версия GCC 11 с поддержкой модулей? Насколько я понимаю, если я соберу последний снимок GCC 11, большинство других специфичных для C++20 кодов должны работать? (или просто придерживаться версии по умолчанию (g++ (Debian 10.2.1-1) 10.2.1 20201207), поставляемой моим дистрибутивом?)
Я новичок, пытающийся изучить С++, я понял, что с момента импорта <iostream>; метод считается «лучшим» решением по сравнению с методом #include <iostream>. Я мог бы также начать использовать более новый/лучший способ сделать это. Но я думаю, что пока мне придется использовать метод #include. Спасибо за ответ!
Я полностью согласен, но я видел только рабочие реализации модулей с компилятором MSVC. Возможно, вам придется подождать некоторое время, прежде чем он будет реализован в GCC или Clang.
Думаю, я отвечу на свой вопрос.
Когда я следую инструкциям на вики GCC (https://gcc.gnu.org/wiki/cxx-modules), это более новая версия по сравнению с той, что находится на svn.
У svn есть версия 10 gcc, а у github — версия 11.
Когда я компилирую версию для github (g++ (GCC) 11.0.0 20201217 (экспериментальная) [версия c++-модулей 20201220-2203]), примеры, предоставленные GCC Wiki, компилируются и работают. Эти файлы привет.cpp:
module;
#include <iostream>
#include <string_view>
export module hello;
export void greeter (std::string_view const &name)
{
std::cout << "Hello " << name << "!\n";
}
И main.cpp
import hello;
int main (void)
{
greeter ("world");
return 0;
}
Команда для компиляции: g++ -fmodules-ts hello.cpp main.cpp
Насколько я понимаю, важен порядок исходных файлов, поэтому hello.cpp должен быть скомпилирован перед main.cpp.
Так что на данный момент кажется, что работают только пользовательские модули, но не стандартные библиотечные (для них #include все еще требуется).
[редактировать] Похоже, что поддержка модулей теперь объединена с основной веткой gcc-11, поэтому использование девелоперских сборок через git или svn больше не требуется (к сожалению, заголовки стандартных библиотек вроде еще не конвертированы в модули, поэтому на данный момент import ; не работает).
Вы можете преобразовать заголовки std_lib в модули с помощью g++ -c -fmodules-ts -x c++-system-header -std=c++20 iostream string vector
Как построить модуль и код, который использует модуль отдельно?
@debashish.ghosh - Предположительно, вы имеете в виду «Как мне получить отдельный интерфейс и реализацию при написании собственного модуля?». Ответ интересный. В файле интерфейса вы говорите export module foo;, а затем имеете операторы экспорта для каждого имени, которое вы хотите, чтобы модуль предоставил другим. В реализации вместо этого вы говорите module foo;. В файле реализации не должно быть операторов экспорта.
Большое спасибо за этот ответ! Он работает на CMake 3.18.4. Как указано в приведенном выше решении, убедитесь, что источники, которые являются (определяемыми пользователем) модулями, являются ПЕРВЫМИ при перечислении их в вашей переменной ${SOURCES}. И не забудьте добавить set(CMAKE_CXX_FLAGS "-fmodules-ts") в свой CMakeList.txt ;) Еще раз спасибо!
Я собрал // Ex1_01.cpp исходный файл из вопроса двумя командами:
$ g++ -std=c++20 -fmodules-ts -xc++-system-header iostream
$ g++ -std=c++20 -fmodules-ts -o Ex1_01 Ex1_01.cpp
После запуска Ex1_01 у меня есть:
The answer to life, the universe, and everything is 42
Для следующего кода в Linux Ubuntu 20.04
import <iostream>;
import <limits>;
int main()
{
int min{ std::numeric_limits<int>::max()};
int max{ std::numeric_limits<int>::min() };
bool any { false };
int x;
while(std::cin >> x)
{
any = true;
if (x < min)
min = x;
if (x> max)
max = x;
}
if (any)
std::cout<<"min = "<<min<<"\nmax = "<<max<<'\n';
}
Я должен был установить g++-11 тогда
g++-11 -std=c++20 -fmodules-ts -xc++-system-header iostream
g++-11 -std=c++20 -fmodules-ts -xc++-system-header limits
g++-11 -std=c++20 -fmodules-ts list0201.cpp -o list0201
$ ./list0201
10
20
-100
ctrl+D
min = -100
max = 20
Если вы пытаетесь изучить модули, вы запутались. Если вы новичок и пытаетесь немного изучить C++, то практический подход к продолжению обучения — вернуться к старому синтаксису include include <iostream> :)