Современный Fortran предлагает несколько кроссплатформенных механизмов для записи версии компилятора и настроек, используемых для создания приложения. Какие методы есть у C++ 17 для сбора этой информации? Книга Хортона и Ван Верта, Начиная с C++ 17, похоже, не отвечает на этот вопрос.
Обзор инструментов Fortran приведен ниже.
iso_fortran_env в Фортране предоставляет стандартный способ доступа к версии компилятора и настройкам, используемым для компиляции кода. Далее следует образец фрагмента.
program check_compiler
use, intrinsic :: iso_fortran_env, only : compiler_options, compiler_version
implicit none
write ( *, 100 ) "compiler version = ", compiler_version ()
write ( *, 100 ) "compiler options = ", trim ( compiler_options () )
100 format ( A, A, / )
stop "normal termination . . ."
end program check_compiler
$ gfortran -o check_compiler check_compiler.f08
$ ./check_compiler
compiler version = GCC version 8.0.0 20170604 (experimental)
compiler options = -fPIC -mmacosx-version-min=10.12.7 -mtune=core2
STOP normal termination . . .
Команды Fortran, такие как execute_command_line, get_command и get_environment_variable, предлагают другой способ записи информации во время компиляции.
Я создал Makefile, который будет выводить параметры в виде текста в файл заголовка, например #define CXX_OPTIONS "blah blah blah", который я мог бы затем вывести, если пользователь набрал coolapp --help. Что было больше для меня и других разработчиков в команде, но это было полезно.





Каждый компилятор вводит свои собственные токены препроцессора, указывающие, что он был скомпилирован ими и какая версия. Эти токены являются кросс-платформенными на компиляторах, которые компилируются более чем на одной платформе, например icc, gcx и clang.
Теперь существуют стандартные способы определения существования некоторых файлов заголовков srd. Boost имеет обширные заголовки, которые декодируют возможности компилятора на основе множества методов.
__cplusplus по идее определяется до стандартной версии, но компиляторы врут.
Обыскивая Стандартный черновик C++ 20, доступный на GitHub, я нахожу Нет результатов для близко локализованных "компилятора" и "версии", и я не нашел ничего подобного, глядя на текст стандарта.
C++ 20 в настоящее время все еще очень близок к C++ 17, и, конечно, такой механизм не был удален, поэтому я думаю, что можно с уверенностью сказать, что в C++ 20 такого нет.
What methods does C++17 have to capture this information?
Никто. Стандарт C++ даже не признает понятие «компилятор» или «параметры»; есть просто «реализация».
Более того, это не имеет смысла, поскольку разные файлы C++, связанные в одну и ту же программу, могут быть скомпилированы с разными параметрами. И я говорю не только о DLL / SO; теоретически вы можете статически связывать файлы, которые были скомпилированы с разными параметрами или даже с разными версиями компилятора.
У разных компиляторов есть способы указать, какая у них версия с помощью макросов. Но у каждого свой способ сообщить об этом.
Эти предостережения обычно относятся также к аспектам Fortran. Так, может быть, между Фортраном и С ++ может быть более близкое соответствие?
@Nicol Bolas: Точка взята хорошо. При использовании таких инструментов, как Spack, который строит все дерево зависимостей, у нас есть некоторый контроль над средой компиляции. Команда cat proc/version открывает системный компилятор. Было бы неплохо запросить сборки Spack и подтвердить версию и настройки компилятора. Мы можем сделать это в наших файлах Fortran. Была надежда, что C++ предлагает аналогичный инструмент.
Стандарт языка определяет макросы __cplusplus, которые кодируют версию стандарта, которую, по заявлению компилятора, поддерживает. Он расширяется до 201703L в компиляторе C++ 17, 201710L в компиляторе C++ 14 и т. д. Он также может определять _STDC и _STDC_VERSION. Помимо этого, все является расширением для конкретного производителя, которое вы должны найти в руководстве к вашему компилятору.
Некоторые, но не все компиляторы, включая GCC и Clang, предопределяют макрос с именем __VERSION__, который расширяется до строки, описывающей версию компилятора. Вы можете проверить это с помощью #ifdef. Кроме того, многие компиляторы содержат макросы, которые расширяются до номеров версий, которые вы можете преобразовывать в строки и объединять. Однако имейте в виду, что некоторые компиляторы рассматривают их как тесты совместимости и будут утверждать, что это другой компилятор, если вы спросите. Помимо собственных номеров версий, Clang определяет __GNUC__, __GNUC_VERSION__ и __GNUC_PATCHLEVEL__, чтобы указать на его совместимость с GCC, а версия для Windows также определяет _MSC_VER, _MSC_FULL_VER и т. д. В режиме совместимости с Microsoft.
Поэтому вы можете создать сложный набор вложенных блоков #elif для распознавания макросов версий различных компиляторов, но он никогда не может быть полным или совместимым с будущими версиями.
Это не отвечает на вопрос. Вернее, делает это невероятно окольным путем, просто говоря «нет».
@NeilButterworth В нем указано, что доступно. Как вы думаете, явное «нет» добавит этому значимости?
1) Нет, такого не предусматривает. 2) Не совсем понимаю, о чем вы спрашиваете - вы можете использовать такие функции, как std :: getenv (), для запроса переменных среды.