AIX unix 服务器上的 g++ 编译错误
g++ compilation error on AIX unix server
我有一个用 C++ 编写的套接字程序服务器代码。
我在使用 g++ 编译器(OS : Unix AIX)编译时遇到以下错误。使用 cc 编译器 (OS : Unix Sun OS ) 成功编译了相同的代码。请告诉我如何解决它。
代码片段
enum sockStates
{
inopen = ios::in,
outopen = ios::out,
open = ios::in | ios::out,
};
错误
g++ -gxcoff -maix64 -shared -fpic -fpermissive -w -libstd=c++11ox -I/devt/flex/java/include -I/devt/flex/java/include/aix -I/tmp/ribscomp/server/include -c -o server.o server.cc
ssocket.h:721:26: error: calls to overloaded operators cannot appear in a constant-expression
open = ios::in | ios::out,
^
g++版本
g++ -v
使用内置规格。
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/4.8.2/lto-wrapper
Target: powerpc-ibm-aix7.1.0.0
Configured with: ../gcc-4.8.2/configure --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --enable-version-specific-runtime-libs --disable-nls --enable-decimal-float=dpd --host=powerpc-ibm-aix7.1.0.0
Thread model: aix
gcc version 4.8.2 (GCC)
问题在于GCC的标准库将std::ios::openmode
定义为带有重载运算符的枚举类型,而在C++03中这些运算符不允许出现在常量表达式中(例如枚举器)。
它适用于 Solaris 编译器,因为(我假设)openmode
只是一个整数类型。该标准允许两者之一,因此两个编译器都符合标准。
在 C++11 模式下,运算符是 constexpr
并且可以在这里使用,因此一种解决方案是使用 -std=c++11
或 -std=gnu++11
进行编译,但请注意 ABI对于 C++11 类型在 GCC 4.8 中没有最终确定。
另一个解决方案是用常量变量替换枚举器:
enum sockstates { _max = std::numeric_limits<int>::max() };
const sockstates inopen = ios::in;
const sockstates outopen = ios::out;
const sockstates open = ios::in | ios::out;
无论是否有错误都不要这样做。这些是 std::ios_base::openmode
类型的枚举器,您想使用这种类型,而不是您自己的枚举类型。如果你真的想要 rename/alias 标准库实体:
namespace sockStates
{
static const ios::openmode
inopen = ios::in,
outopen = ios::out,
open = ios::in | ios::out;
};
虽然我不推荐这个。只需在任何地方显式使用 ios::in | ios::out
即可。普通的 C++ 程序员立即知道这意味着什么。
我有一个用 C++ 编写的套接字程序服务器代码。
我在使用 g++ 编译器(OS : Unix AIX)编译时遇到以下错误。使用 cc 编译器 (OS : Unix Sun OS ) 成功编译了相同的代码。请告诉我如何解决它。
代码片段
enum sockStates { inopen = ios::in, outopen = ios::out, open = ios::in | ios::out, };
错误
g++ -gxcoff -maix64 -shared -fpic -fpermissive -w -libstd=c++11ox -I/devt/flex/java/include -I/devt/flex/java/include/aix -I/tmp/ribscomp/server/include -c -o server.o server.cc ssocket.h:721:26: error: calls to overloaded operators cannot appear in a constant-expression open = ios::in | ios::out, ^
g++版本
g++ -v
使用内置规格。
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/freeware/libexec/gcc/powerpc-ibm-aix7.1.0.0/4.8.2/lto-wrapper
Target: powerpc-ibm-aix7.1.0.0
Configured with: ../gcc-4.8.2/configure --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-languages=c,c++,fortran --prefix=/opt/freeware --mandir=/opt/freeware/man --infodir=/opt/freeware/info --enable-version-specific-runtime-libs --disable-nls --enable-decimal-float=dpd --host=powerpc-ibm-aix7.1.0.0
Thread model: aix
gcc version 4.8.2 (GCC)
问题在于GCC的标准库将std::ios::openmode
定义为带有重载运算符的枚举类型,而在C++03中这些运算符不允许出现在常量表达式中(例如枚举器)。
它适用于 Solaris 编译器,因为(我假设)openmode
只是一个整数类型。该标准允许两者之一,因此两个编译器都符合标准。
在 C++11 模式下,运算符是 constexpr
并且可以在这里使用,因此一种解决方案是使用 -std=c++11
或 -std=gnu++11
进行编译,但请注意 ABI对于 C++11 类型在 GCC 4.8 中没有最终确定。
另一个解决方案是用常量变量替换枚举器:
enum sockstates { _max = std::numeric_limits<int>::max() };
const sockstates inopen = ios::in;
const sockstates outopen = ios::out;
const sockstates open = ios::in | ios::out;
无论是否有错误都不要这样做。这些是 std::ios_base::openmode
类型的枚举器,您想使用这种类型,而不是您自己的枚举类型。如果你真的想要 rename/alias 标准库实体:
namespace sockStates
{
static const ios::openmode
inopen = ios::in,
outopen = ios::out,
open = ios::in | ios::out;
};
虽然我不推荐这个。只需在任何地方显式使用 ios::in | ios::out
即可。普通的 C++ 程序员立即知道这意味着什么。