Как написать Мой C++, чтобы быть готовым к модулям c++?

уже есть два компилятора, которые поддерживают модули c++:

при запуске нового проекта сейчас, на что я должен обратить внимание, чтобы иметь возможность принять функцию модулей, когда она в конечном итоге будет выпущена в моем компиляторе?

Это возможно ли использовать модули и поддерживать совместимость со старыми компиляторами, которые его не поддерживают?

2 ответов


уже есть два компилятора, которые поддерживают модули c++

лязг:http://clang.llvm.org/docs/Modules.html MS VS 2015: http://blogs.msdn.com/b/vcblog/archive/2015/12/03/c-modules-in-vs-2015-update-1.aspx

подход Microsoft, по-видимому, набирает наибольшую тягу, главным образом потому, что Microsoft бросает гораздо больше ресурсов на их реализацию, чем любой из людей clang в настоящее время. Смотри https://llvm.org/bugs/buglist.cgi?list_id=100798&query_format=advanced&component=Modules&product=clang для того, что я имею в виду, есть некоторые большие ошибки showstopper в модулях для C++, тогда как модули для C или особенно Objective C выглядят гораздо более пригодными для использования в реальном коде. Крупнейший и самый важный клиент Visual Studio, Microsoft, упорно настаивает на модулях, потому что он решает целую тонну внутренних проблем масштабируемости сборки, а внутренний код Microsoft является одним из самый сложный C++ для компиляции в любом месте, поэтому вы не можете бросить на него никакой компилятор, кроме MSVC (например, удачи в получении clang или GCC для компиляции 40K линейных функций). Поэтому трюки сборки clang, используемые Google и т. д., недоступны для Microsoft, и у них есть огромная насущная необходимость исправить это раньше, чем позже.

Это не значит, что нет серьезных недостатков в дизайне с предложением Microsoft, когда оно применяется на практике к большим кодовым базам реального мира. Однако Габи считает, что вы должны переработать свой код для модулей, и хотя я не согласен, я вижу, откуда он исходит.

при запуске нового проекта сейчас, на что я должен обратить внимание, чтобы иметь возможность принять функцию модулей, когда она в конечном итоге будет выпущена в моем компиляторе?

поскольку компилятор Microsoft в настоящее время должен реализовывать модули, вы должны убедиться, что ваша библиотека может использоваться во всех из них формы:

  1. динамическая библиотека
  2. статическая библиотека
  3. только заголовок библиотеки

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

более поздняя Visual Studio позволит связать файл определения модуля (the .IFC file)как ресурс в DLL. Это, наконец, устранит необходимость .lib и .dll различие на MSVC, вы просто поставляете одну DLL компилятору, и все это "просто работает" при импорте модуля, без заголовков или чего-либо еще. Это, конечно, пахнет немного как COM, но без большинства преимуществ COM.

можно ли использовать модули в одном коде и по-прежнему поддерживать совместимость со старыми компиляторами, которые не поддерживают его?

Я собираюсь предположить, что вы имели в виду жирный текст выше.

ответ, в целом, да с еще более препроцессора макрос удовольствие. #include <someheader> может превратиться в import someheader внутри заголовка, потому что препроцессор по-прежнему работает как обычно. Поэтому вы можете пометить отдельные заголовки библиотек с поддержкой модулей C++ примерно так:

// someheader.hpp

#if MODULES_ENABLED
#  ifndef EXPORTING_MODULE
import someheader;  // Bring in the precompiled module from the database
// Do NOT set NEED_DEFINE so this include exits out doing nothing more
#  else
// We are at the generating the module stage, so mark up the namespace for export
#    define SOMEHEADER_DECL export
#    define NEED_DEFINE
#  endif
#else
// Modules are not turned on, so declare everything inline as per the old way
#  define SOMEHEADER_DECL
#  define NEED_DEFINE
#endif

#ifdef NEED_DEFINE
SOMEHEADER_DECL namespace someheader
{
  // usual classes and decls here
}
#endif

теперь в главном.cpp или что-то еще, вы просто делаете:

#include "someheader.hpp"

... и если компилятор имел / experimental: modules /DMODULES_ENABLED, то ваше приложение автоматически использует выпуск модулей C++ вашей библиотеки. Если это не так, вы получаете встроенное включение, как мы всегда делали.

Я считаю, что это минимальный возможный набор изменений исходного кода, чтобы сделать модули кода готовыми. Вы заметите, что я ничего не сказал о системах сборки, это потому, что я все еще отлаживаю инструмент cmake, который я написал, чтобы все это "просто работало" без проблем, и я ожидаю, что буду отлаживать его в течение нескольких месяцев. Ожидал увидеть это возможно на конференции C++ в следующем году или через год :)


можно ли использовать модули и сохранять совместимость со старыми компиляторами, которые не поддерживают его?

нет, это невозможно. Возможно, можно использовать некоторые #ifdef магия вроде этого:

#ifdef CXX17_MODULES
    ...
#else
    #pragma once, #include "..." etc.
#endif

но это означает, что вы должны предоставить .h поддержка и, таким образом, потерять все преимущества, плюс ваша кодовая база выглядит довольно уродливо сейчас.

если вы хотите следовать этому подходу, самый простой способ обнаружить"CXX17_MODULES" что я просто составлено, чтобы скомпилировать небольшую тестовую программу, которая использует модули с системой сборки по вашему выбору, и определить глобальный для всех, чтобы узнать, удалось ли компиляции или нет.

при запуске нового проекта сейчас, на что я должен обратить внимание, чтобы иметь возможность принять функцию модулей, когда она в конечном итоге будет выпущена в моем компиляторе?

Это зависит. Если ваш проект-enterprise и вы получаете еду на тарелке, я бы подождал несколько годы, как только он выпускается в конюшнях, так что он становится широко адаптированным. С другой стороны, если ваш проект может позволить себе быть кровоточащим, обязательно используйте модули.

в основном, это та же история с Python3 и Python2, или менее релевантно, PHP7 и PHP5. Вам нужно найти баланс между тем, чтобы быть хорошим современным программистом и не раздражать людей на Debian; -)