【问题标题】:How to check the C++ version is being used in Linux OS?如何检查 Linux 操作系统中使用的 C++ 版本?
【发布时间】:2017-07-12 07:05:35
【问题描述】:

我已尝试打印:

std::cout << __cplusplus;

得到 1 作为输出。

我也试过:g++ -version 命令。它产生输出:

g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

如何根据上面的输出判断C++标准的版本??

或者还有其他方法吗??

在某处我发现,Boost.Config 有大量可用于测试对特定 C++11 功能的支持的宏。

【问题讨论】:

  • 什么版本?编译器、库、c++ 标准、c++ 特性?
  • 编程语言 C++ @Klaus 的标准版本
  • 我在答案中添加了 c++version 检查。

标签: c++ linux c++11 boost g++


【解决方案1】:

我已尝试打印:

std::cout << __cplusplus;

得到 1 作为输出

听起来__cplusplus 被强制转换为bool。您可能应该显示完整的代码,而不是简化的 sn-p。

也许您可以将__cplusplus 转换为unsigned 类型。或者,您可能需要包含一个像 &lt;iostream&gt; 这样的 c++ 标头。但是,这样做时我无法重现您的结果:

$ cat test.cxx
#include <iostream>
int main(int argc, char* argv[])
{
    std::cout << __cplusplus << std::endl;
    std::cout << (unsigned int)__cplusplus << std::endl;
    return 0;
}

$ ./test.exe
201402
201402

如何判断上面输出的版本??或者还有其他方法吗??

通常您要求编译器将它们提供给您。另请参阅echo '#include &lt;iostream&gt;' | g++ -x c++ -dM -E - | sort 的输出。下面的一个来自 Fedora 25 和 GCC 6.3。

您可以通过添加-march=native 来为您拥有的特定 CPU 调整更多宏。然后你会看到诸如__AES____PCLMUL____SHA__等预处理器定义。

您还可以使用 -std=c++03-std=c++11-std=c++14 等不同版本的 C++ 标准。

$ echo '#include <iostream>' | g++ -x c++ -dM -E - | sort
#define ADJ_ESTERROR 0x0008
#define ADJ_FREQUENCY 0x0002
#define ADJ_MAXERROR 0x0004
#define ADJ_MICRO 0x1000
#define ADJ_NANO 0x2000
#define ADJ_OFFSET 0x0001
#define ADJ_OFFSET_SINGLESHOT 0x8001
#define ADJ_OFFSET_SS_READ 0xa001
#define ADJ_SETOFFSET 0x0100
#define ADJ_STATUS 0x0010
#define ADJ_TAI 0x0080
#define ADJ_TICK 0x4000
#define ADJ_TIMECONST 0x0020
#define _ALLOCA_H 1
#define alloca(size) __builtin_alloca (size)
#define _ALLOCATOR_H 1
#define _ALLOC_TRAITS_H 1
#define __always_inline __inline __attribute__ ((__always_inline__))
#define __amd64 1
#define __amd64__ 1
#define _ANSI_STDDEF_H
#define _ASM_GENERIC_ERRNO_BASE_H
#define _ASM_GENERIC_ERRNO_H
#define __ASMNAME2(prefix,cname) __STRING (prefix) cname
#define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
#define _ATFILE_SOURCE 1
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_ACQUIRE 2
#define __ATOMIC_CONSUME 1
#define __ATOMIC_HLE_ACQUIRE 65536
#define __ATOMIC_HLE_RELEASE 131072
#define __ATOMIC_RELAXED 0
#define __ATOMIC_RELEASE 3
#define __ATOMIC_SEQ_CST 5
...
#define _T_PTRDIFF
#define _T_PTRDIFF_
#define __try try
#define _T_SIZE
#define _T_SIZE_
#define _T_WCHAR
#define _T_WCHAR_
#define _TYPEINFO
#define __U16_TYPE unsigned short int
#define __U32_TYPE unsigned int
#define __U64_TYPE unsigned long int
#define __u_char_defined
#define __uid_t_defined
#define __UID_T_TYPE __U32_TYPE
#define __UINT16_C(c) c
#define UINT16_C(c) c
#define __UINT16_MAX__ 0xffff
#define UINT16_MAX (65535)
#define __UINT16_TYPE__ short unsigned int
#define UINT16_WIDTH 16
#define __UINT32_C(c) c ## U
#define UINT32_C(c) c ## U
#define __UINT32_MAX__ 0xffffffffU
#define UINT32_MAX (4294967295U)
#define __uint32_t_defined
#define __UINT32_TYPE__ unsigned int
#define UINT32_WIDTH 32
#define __UINT64_C(c) c ## UL
#define UINT64_C(c) c ## UL
#define __UINT64_MAX__ 0xffffffffffffffffUL
#define UINT64_MAX (__UINT64_C(18446744073709551615))
#define __UINT64_TYPE__ long unsigned int
#define UINT64_WIDTH 64
#define __UINT8_C(c) c
#define UINT8_C(c) c
#define __UINT8_MAX__ 0xff
#define UINT8_MAX (255)
#define __UINT8_TYPE__ unsigned char
#define UINT8_WIDTH 8
#define __UINT_FAST16_MAX__ 0xffffffffffffffffUL
#define UINT_FAST16_MAX (18446744073709551615UL)
#define __UINT_FAST16_TYPE__ long unsigned int
#define UINT_FAST16_WIDTH __WORDSIZE
#define __UINT_FAST32_MAX__ 0xffffffffffffffffUL
#define UINT_FAST32_MAX (18446744073709551615UL)
#define __UINT_FAST32_TYPE__ long unsigned int
#define UINT_FAST32_WIDTH __WORDSIZE
#define __UINT_FAST64_MAX__ 0xffffffffffffffffUL
#define UINT_FAST64_MAX (__UINT64_C(18446744073709551615))
#define __UINT_FAST64_TYPE__ long unsigned int
#define UINT_FAST64_WIDTH 64
#define __UINT_FAST8_MAX__ 0xff
#define UINT_FAST8_MAX (255)
#define __UINT_FAST8_TYPE__ unsigned char
#define UINT_FAST8_WIDTH 8
#define __UINT_LEAST16_MAX__ 0xffff
#define UINT_LEAST16_MAX (65535)
#define __UINT_LEAST16_TYPE__ short unsigned int
#define UINT_LEAST16_WIDTH 16
#define __UINT_LEAST32_MAX__ 0xffffffffU
#define UINT_LEAST32_MAX (4294967295U)
#define __UINT_LEAST32_TYPE__ unsigned int
#define UINT_LEAST32_WIDTH 32
#define __UINT_LEAST64_MAX__ 0xffffffffffffffffUL
#define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615))
#define __UINT_LEAST64_TYPE__ long unsigned int
#define UINT_LEAST64_WIDTH 64
#define __UINT_LEAST8_MAX__ 0xff
#define UINT_LEAST8_MAX (255)
#define __UINT_LEAST8_TYPE__ unsigned char
#define UINT_LEAST8_WIDTH 8
#define __UINTMAX_C(c) c ## UL
#define UINTMAX_C(c) c ## UL
#define __UINTMAX_MAX__ 0xffffffffffffffffUL
#define UINTMAX_MAX (__UINT64_C(18446744073709551615))
#define __UINTMAX_TYPE__ long unsigned int
#define UINTMAX_WIDTH 64
#define __u_intN_t(N,MODE) typedef unsigned int u_int ##N ##_t __attribute__ ((__mode__ (MODE)))
#define __UINTPTR_MAX__ 0xffffffffffffffffUL
#define UINTPTR_MAX (18446744073709551615UL)
#define __UINTPTR_TYPE__ long unsigned int
#define UINTPTR_WIDTH __WORDSIZE
#define __ULONG32_TYPE unsigned int
#define __ULONGWORD_TYPE unsigned long int
#define __unix 1
#define __unix__ 1
#define unix 1
#define __UQUAD_TYPE unsigned long int
#define __USE_ATFILE 1
#define __useconds_t_defined
#define __USECONDS_T_TYPE __U32_TYPE
#define __USE_FORTIFY_LEVEL 0
#define __USE_GNU 1
#define __USE_ISOC11 1
#define __USE_ISOC95 1
#define __USE_ISOC99 1
#define __USE_ISOCXX11 1
#define __USE_LARGEFILE 1
#define __USE_LARGEFILE64 1
#define __USE_MISC 1
#define __USE_POSIX 1
#define __USE_POSIX199309 1
#define __USE_POSIX199506 1
#define __USE_POSIX2 1
#define __USER_LABEL_PREFIX__
#define __USE_UNIX98 1
#define __USE_XOPEN 1
#define __USE_XOPEN2K 1
#define __USE_XOPEN2K8 1
#define __USE_XOPEN2K8XSI 1
#define __USE_XOPEN2KXSI 1
#define __USE_XOPEN_EXTENDED 1
#define __USING_NAMESPACE_C99(name)
#define __USING_NAMESPACE_STD(name)
#define __UWORD_TYPE unsigned long int
#define __va_arg_pack() __builtin_va_arg_pack ()
#define __va_arg_pack_len() __builtin_va_arg_pack_len ()
#define _VA_LIST_DEFINED
#define __VERSION__ "7.1.1 20170622 (Red Hat 7.1.1-3)"
#define __WALL 0x40000000
#define __warnattr(msg) __attribute__((__warning__ (msg)))
#define __warndecl(name,msg) extern void name (void) __attribute__((__warning__ (msg)))
#define _WCHAR_H 1
#define __WCHAR_MAX__ 0x7fffffff
#define __WCHAR_MAX __WCHAR_MAX__
#define WCHAR_MAX __WCHAR_MAX
#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
#define __WCHAR_MIN __WCHAR_MIN__
#define WCHAR_MIN __WCHAR_MIN
#define __wchar_t__
#define __WCHAR_T
#define __WCHAR_T__
#define _WCHAR_T
#define _WCHAR_T_
#define _WCHAR_T_DECLARED
#define _WCHAR_T_DEFINED
#define _WCHAR_T_DEFINED_
#define _WCHAR_T_H
#define __WCHAR_TYPE__ int
#define __WCHAR_WIDTH__ 32
#define WCHAR_WIDTH 32
#define __WCLONE 0x80000000
#define __W_CONTINUED 0xffff
#define WCONTINUED 8
#define __WCOREDUMP(status) ((status) & __WCOREFLAG)
#define __WCOREFLAG 0x80
#define _WCTYPE_H 1
#define WEOF (0xffffffffu)
#define __W_EXITCODE(ret,sig) ((ret) << 8 | (sig))
#define WEXITED 4
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
#define WEXITSTATUS(status) __WEXITSTATUS (status)
#define __WIFCONTINUED(status) ((status) == __W_CONTINUED)
#define WIFCONTINUED(status) __WIFCONTINUED (status)
#define WIFEXITED(status) __WIFEXITED (status)
#define __WIFEXITED(status) (__WTERMSIG(status) == 0)
#define __WIFSIGNALED(status) (((signed char) (((status) & 0x7f) + 1) >> 1) > 0)
#define WIFSIGNALED(status) __WIFSIGNALED (status)
#define __WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
#define WIFSTOPPED(status) __WIFSTOPPED (status)
#define __WINT_MAX__ 0xffffffffU
#define WINT_MAX (4294967295u)
#define WINT_MIN (0u)
#define __WINT_MIN__ 0U
#define _WINT_T
#define __WINT_TYPE__ unsigned int
#define __WINT_WIDTH__ 32
#define WINT_WIDTH 32
#define WNOHANG 1
#define __WNOTHREAD 0x20000000
#define WNOWAIT 0x01000000
#define __WORDSIZE 64
#define __WORDSIZE_TIME64_COMPAT32 1
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
#define WSTOPPED 2
#define __WSTOPSIG(status) __WEXITSTATUS(status)
#define WSTOPSIG(status) __WSTOPSIG (status)
#define __WTERMSIG(status) ((status) & 0x7f)
#define WTERMSIG(status) __WTERMSIG (status)
#define WUNTRACED 2
#define __wur
#define __x86_64 1
#define __x86_64__ 1
#define _XLOCALE_H 1
#define _XOPEN_SOURCE 700
#define _XOPEN_SOURCE_EXTENDED 1

【讨论】:

    【解决方案2】:

    如果您想要 c++ 中的特定功能,可以使用此处描述的宏: 例如你想知道 lib chrono 是否可用:__cpp_lib_chrono 包含一个值 201510

    http://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros

    可以通过__cplusplus查看所用c++标准的版本。对于 c++17,值为“201703”,对于 c++14,值为“201402”。但是,如果编译器似乎启用了 c++14,您应该记住,并非所有功能都必须存在。对于特定功能,您可以查看上面的宏。问题的这个特定部分在这里已经有了答案: How to determine the version of the C++ standard used by the compiler?

    gcc 例如也有预定义的宏来检查,例如:__GNUC__

    https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

    您是否想在编译期间或之前进行检查有点不清楚,例如在配置步骤中。

    如果您想了解配置步骤中的某些内容,您可以编写小型测试程序来测试上述宏并将结果写入标准输出,以便您可以检查 gmake 或 autotools。

    您还可以检查 Makefile 中的内容并通过使用 -D 标志定义宏与您的编译器共享该信息。

    【讨论】:

      【解决方案3】:

      我已尝试打印:

      std::cout << __cplusplus;
      

      得到 1 作为输出

      根据How to determine the version of the C++ standard used by the compiler?,这是g++ 4.4.7 的预期行为

      gcc(显然近 10 年)将此值设置为 1 ... 直到 gcc 4.7.0 出来时它被修复。

      另一种解决方案是保留您的 __cplusplus 方法并升级到 g++ 4.7.0 或更高版本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-21
        • 1970-01-01
        • 1970-01-01
        • 2019-03-01
        • 2012-02-05
        • 2019-02-09
        • 2020-06-13
        相关资源
        最近更新 更多