#include <stdio.h>
int main(void) {
#ifdef __STDC_VERSION__
printf("Aparentemente compatible con __STDC_VERSION__\n");
# if __STDC_VERSION__ == 199901L
printf("Este código fue compilando con el estandar C99.\n");
# elif __STDC_VERSION__ == 201112L
printf("Este codigo fue compilado con el estandar C11.\n");
# else
printf("Este codigo fue compilado con el estandar C94.\n");
# endif /* == */
#endif /* __STDC_VERSION__ */
#ifdef __cplusplus
printf("Aparentemente compilado con un compilador de C++\n");
# if __cplusplus >= 201103L
printf("Este codigo fue compilado bajo un estandar mayor o igual a C++11.\n");
# else
printf("Este codigo fue compilado bajo un estandar menor a C++11.");
# endif /* >= */
#endif /* __cplusplus */
#ifdef __STDC__
printf("Aparentemente compatible con __STDC__ y los estandares C89 y C90 ...\n");
#endif /* __STDC__ */
}
在 C99 标准下运行时:
gcc -o test -std=c99 test.c
我得到以下结果:
Aparentemente compatible con __STDC_VERSION__
Este código fue compilando con el estandar C99.
Aparentemente compatible con __STDC__ y los estandares C89 y C90
如果我使用 C11 标准下的 C++ 编译器编译它:
g++ -o test -std=c++11 test.c
可以得到以下结果:
Aparentemente compilado con un compilador de C++
Este codigo fue compilado bajo un estandar mayor o igual a C++11.
Aparentemente compatible con __STDC__ y los estandares C89 y C90 ...
使用该代码,您可以知道您当前正在编译哪个标准,即使使用哪个编译器(不是它的名称,而是语言)。
1:本标准不支持gcc。 2:这个宏在所有标准中定义为1,但它的行为可能因编译器而异,所以它并不完全可靠,除非你想知道你是否在 C 编译器中使用 C 编译器进行编译。C++ 会不要抛出你的定义。
了解您正在编译的标准版本的最佳方法是使用预处理器宏:
__STDC_VERSION__
,它从 C99 开始可用,并且它的值与以下版本一起加载:__STDC_VERSION__ == 199409L
标准是C94
1。__STDC_VERSION__ == 199901L
标准是C99
。__STDC_VERSION__ == 201112L
是标准是C11
。对于其他标准,定义了预处理器宏:
__ANSI__
适用于 ANSI C(C89 和 C90)__STDC__
ANSI C 2类似。可以找到截至 2014 年的标准列表:
尝试以下程序作为示例:
在 C99 标准下运行时:
我得到以下结果:
如果我使用 C11 标准下的 C++ 编译器编译它:
可以得到以下结果:
使用该代码,您可以知道您当前正在编译哪个标准,即使使用哪个编译器(不是它的名称,而是语言)。
1:本标准不支持
gcc
。2:这个宏在所有标准中定义为
1
,但它的行为可能因编译器而异,所以它并不完全可靠,除非你想知道你是否在 C 编译器中使用 C 编译器进行编译。C++ 会不要抛出你的定义。参考:
作为附加信息,我想添加 C++ 功能存在宏。
一段简短的历史。
2011 年的 C++ 标准(最初称为 C++0x,后来称为 C++11)是批准最慢的标准(之前的标准是从 1998 年1开始的)。
C++11 为 C++ 语言添加了许多新特性,以至于它使 C++ 看起来像是一门新语言。鉴于编译器开发人员需要实现大量功能,长期以来,编译器对 C++11 标准的遵守情况参差不齐且不完整。
这使得有必要能够检查单个语言特性而不是标准(因为编译器可能声称是 C++11 但缺少一些 C++11 特性);为了使这成为可能,创建了功能存在宏。
功能存在宏。
功能存在宏允许您检查特定 C++ 功能是否在当前 C++ 编译器中实现。
特征分为库特征和语言特征,因此宏遵循以下格式:
功能宏列表。
C++17__cpp_noexcept_function_type
:使异常规范成为函数签名的一部分。P0012R1。__cpp_fold_expressions
: 可分组的表达式。N4191、N4295。__cpp_static_assert
: 的扩展名static_assert
。N3928。__cpp_namespace_attributes
: 命名空间的属性。N4196,N4266。__cpp_enumerator_attributes
: 枚举的属性。__cpp_nested_namespace_definitions
: 嵌套命名空间定义。N4230。__cpp_inheriting_constructors
: 遗留构造函数的扩展。P0136R0,P0136R1。__cpp_nontype_template_args
:允许不断评估非类型化模板参数。N4198,N4268。__cpp_lib_uncaught_exceptions
: 实用程序std::uncaught_exceptions
。N4152,N4259。__cpp_lib_as_const
: 实用程序std::as_const
。P0007R1。__cpp_lib_transparent_operators
:透明运营商(灵活std::owner_less
)。P0074R0。__cpp_lib_invoke
: 实用程序std::invoke
。N4169。__cpp_lib_void_t
: 实用程序std::void_t
。N3911。__cpp_lib_bool_constant
: 实用程序std::bool_constant
。[N4389]8 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4389.html)。__cpp_lib_type_trait_variable_templates
: 实用程序std::is_void_v
。P0006R0。__cpp_lib_logical_traits
: 逻辑特征。P0013R1。__cpp_lib_chrono
std::chrono::duration
:和的舍入函数std::chrono::time_point
。P0092R1。__cpp_lib_allocator_traits_is_always_equal
:清理标准库,删除noexcept
. N4258。__cpp_lib_incomplete_container_elements
: 标准容器的不完整类型。N4510。__cpp_lib_map_try_emplace
,__cpp_lib_map_try_emplace
,__cpp_lib_unordered_map_try_emplace
: 对插入界面的改进std::map::try_emplace
,std::map::insert_or_assign
以及它们在std::unordered_map
. N4279。__cpp_lib_nonmember_container_access
:通过免费功能统一访问容器实用程序。N4280。__cpp_lib_shared_mutex
:没有时间限制的共享互斥锁。N4508。__cpp_lib_lock_guard_variadic
:std::lock_guard
可变参数实用程序。P0156R0。__cpp_binary_literals
: 二进制字面量。N3472。__cpp_init_captures
: lambda 中的广义捕获。N3610,N3648。__cpp_generic_lambdas
: 通用 lambda。N3649。__cpp_sized_deallocation
:delete
有大小的运算符。N3778。__cpp_constexpr
: 放宽限制constexpr
。N3652。__cpp_decltype_auto
,__cpp_return_type_deduction
: 函数中返回类型的推导。N3638。__cpp_aggregate_nsdmi
:聚合中的成员初始值设定项。N3653。__cpp_variable_templates
:模板变量。N3651。__cpp_lib_integer_sequence
: 实用程序std::integer_sequence
。N3658。__cpp_lib_exchange_function
: 实用程序std::exchange()
。N3668。__cpp_lib_tuples_by_type
:按类型访问元组成员。N3670。__cpp_lib_tuple_element_t
: 实用程序std::tuple_element_t
。N3887。__cpp_lib_make_unique
: 实用程序std::make_unique
。N3656。__cpp_lib_transparent_operators
:透明运营商(灵活std::greater
)。N3421。__cpp_lib_integral_constant_callable
: 呼叫接线员std::integral_constant
。N3545。__cpp_lib_transformation_trait_aliases
:关于转换特征的实用程序。N3655。__cpp_lib_result_of_sfinae
: SFINAE技术的资助。N3462。__cpp_lib_is_final
: 实用程序std::is_final
。轻型工作组 2112。__cpp_lib_is_null_pointer
: 实用程序std::is_null_pointer
。轻型工作组 2247。__cpp_lib_chrono_udls
,__cpp_lib_string_udls
: 标头类型的用户定义文字<chrono>
和<string>
. N3642。__cpp_lib_generic_associative_lookup
:关联容器中的异构比较。N3657。__cpp_lib_null_iterators
: 空迭代器。N3644。__cpp_lib_make_reverse_iterator
: 实用程序std::make_reverse_iterator
。轻型工作组 2285。__cpp_lib_robust_nonmodifying_seq_ops
:为不修改序列的操作提供更大的鲁棒性(std::mismatch
和std::equal
)std::is_permutation}
。N3671。__cpp_lib_complex_udls
: 类型的用户定义文字std::complex
。N3779。__cpp_lib_quoted_string_io
: 实用程序std::quoted
。N3654。__cpp_lib_shared_timed_mutex
: 实用程序std::shared_timed_mutex
。N3891。__cpp_unicode_characters
,__cpp_raw_strings
,__cpp_unicode_literals
: Unicode 和原始文本。N2249。N2442。__cpp_user_defined_literals
:用户定义的文字。N2765。__cpp_lambdas
: 拉姆达斯。N2927。__cpp_constexpr
: 常量表达式。N2235。__cpp_range_based_for
for
:范围循环。N2930。__cpp_static_assert
: 静态断言。N1720。__cpp_decltype
: 键入查询运算符decltype
。N2343。__cpp_attributes
: C++ 属性。N2761。__cpp_rvalue_references
:对右侧数值的引用。N2118。__cpp_variadic_templates
:可变参数模板。N2242。__cpp_initializer_lists
: 初始化列表。N2672。__cpp_explicit_conversion
: 显式转换运算符。N2437。__cpp_delegating_constructors
: 委托构造函数。N1986 .__cpp_nsdmi
: 非静态成员数据的初始化。N2756。__cpp_inheriting_constructors
: 遗留构造函数。N2540。__cpp_ref_qualifiers
: 参考限定词。N2439。__cpp_alias_templates
: 模板别名。N2258。1 2003 年有一个名为 C++03 的非官方标准,它实际上不是标准本身,而是技术规范的集合。