编译器兼容性
本节介绍编译器功能以及影响 Oracle Developer Studio 和 GCC 之间兼容性的其他行为。
实现定义的行为
C 和 C++ 标准中的某些部分保留为“实现定义的行为”。这些详细信息在 GCC 和 Oracle Developer Studio 文档中定义,而且它们在某些方面存在一定差异。
位字段和枚举类型既可以带符号,也可以不带符号,具体由编译器选择。对于 enum,编译器如何选择因枚举值列表而异。Oracle Developer Studio C 和 C++ 的行为与 gcc 的行为不同。
带符号和不带符号 int 位字段
声明为 int(而不是 signed int 或 unsigned int)的位字段可以由编译器使用带符号或不带符号类型实现。提取值并决定是否对其进行符号扩展时,编译器如何选择便会体现出不同。
Oracle Developer Studio 编译器为 int 位字段使用不带符号类型,而 gcc 编译器使用带符号类型。使用 gcc –funsigned-bitfields 标志可控制此行为。
有关更多信息,请参见 https://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/Non_002dbugs.html 上的第六个列表项。
带符号和不带符号 enum 类型
C 和 C++ 中的 enum 类型可由编译器使用带符号或不带符号类型加以实现。它可能会依赖于特定类型的枚举值,因此很难预测。在这方面,Oracle Developer Studio 编译器的行为与 gcc 不同。Oracle Developer Studio 编译器为 enum 使用带符号值,而 gcc 编译器使用不带符号类型,除非 enum 类型的某些值明确分配了负值。
了解声明为 enum 类型的位字段的实现差异留给读者去做练习。最好更新源代码,使其具有更好的可移植性。对于位字段,您只需根据代码编写方式,将 “int” 声明更新为 “signed” 或 “unsigned” 即可。对于 enum 类型,您可以在需要将其转换为整数且不依赖于缺省类型时转换该类型。
C 语言扩展
Oracle Developer Studio 中的许多 C 语言扩展还通过 Oracle Developer Studio C++ 进行了实现。Oracle Developer Studio 12.5:C 用户指南 中的 扩展中介绍了一些 C 扩展。有关 gcc 语言扩展的列表,请参见 GCC 文档中的 Extensions to the C Language Family(C 语言系列的扩展)。
gcc 表中列出的部分项目现在是相关语言标准的标准功能,并在表 1中列为 C11、C99、C++03、C++11 和 C++14。
根据较早的语言标准编译时,较新的语言标准的功能通常作为扩展提供,除非它们与现有代码冲突,或者您使用选项启用了严格一致性模式。有关不同模式中可用的功能的更多信息,请参见该编译器的文档。
下表列出了在 Oracle Developer Studio 中实现的扩展。
表 1 在 Oracle Developer Studio 中实现的 GCC 扩展
|
|
语句表达式:将语句和声明放在表达式中。
|
已实现。
|
局部标签:块的局部标签。
|
仅在 C 中实现。
|
作为值的标签:获取标签指针及计算的 gotos。
|
仅在 C 中实现。
|
嵌套函数:就像在 Algol 和 Pascal 中一样,函数的词法作用域。
|
未实现。
|
构造调用:向另一个函数发出调用。
|
未实现。
|
Typeof:指的是表达式类型。
|
已实现。Oracle Developer Studio 12.5 C++ C++11 中的新功能,为此定义了 decltype。在 Sun (–compat=5) 模式下,C++ 会忽略 typeof 关键字,但仍支持 __typeof 和 __typeof__。
|
条件:忽略 ‘?:’ 表达式的中间操作数。
|
仅在 C 中实现。
|
__int128:128 位整数-__int128。
|
未实现。
|
Long Long:双字整数-long long int。
|
已在 C 和 C++ 中实现。
|
Complex:复数的数据类型。
|
非类型化 _Complex 缺省为 double,以便与 gcc 兼容。仅在 C 中实现。
|
浮点类型:其他浮点类型。
|
Oracle Developer Studio C 和 C++ 实现了 128 位 long double 类型,但没有实现名为 __float128 的类型。
|
半精度:半精度浮点。
|
未实现。
|
十进制浮点:十进制浮点类型。
|
未实现。
|
十六进制浮点:十六进制浮点常量。
|
C99。仅在 C 中实现。
|
定点:定点类型。
|
未实现。
|
命名地址空间:命名地址空间。
|
未实现。
|
零长度:零长度数组(常规零长度数组)。
|
int foo[0];
已在 C++ 的 GNU 兼容性模式下实现,或使用 –features=zla 实现。
|
零长度:零长度数组(弹性数组成员)。
|
结构结尾的 int foo[]; //
已在 C++ 的 GNU 兼容性模式下实现,或使用 –features=zla 实现。
|
空结构:不含成员的结构。
|
已实现。使用 C 时,要求 –features=extensions。
|
可变长度:长度在运行时计算的数组。
|
C99。已在 C 和 C++ 中实现。
|
可变参数宏:具有可变数目的参数的宏
|
C99。已在 C 和 C++ 中实现。Oracle Developer Studio 实现了 gcc 扩展,为可变宏参数提供用户定义的名称。缺少可变参数的 gcc 扩展未在 C++ 中实现。
|
转义换行符:转义换行符的规则稍有点宽松。
|
未实现。
|
下标:任何数组都可以带有下标,即便数组不是 lvalue。
|
C99。标准 C++。已在 C 和 C++ 中实现。
|
指针算术运算:对空指针和函数指针执行算术运算。
|
仅在 C 中实现。系统会生成警告。
|
数组指针:具有限定符的数组指针会按预期工作。
|
未实现。
|
初始化程序:非常量初始化程序。
|
C99。标准 C++。已实现。
|
复合文字:复合文字用来向结构、联合或数组提供值。
|
C99。已在 C 中实现。
|
指定的初始化程序:标记初始化程序的元素。
|
C99。已在 C 中实现。
|
case 范围:`case 1 ... 9` 等。
|
已实现。
|
转换为联合:从联合中的任何成员转换为 union 类型。
|
未实现。
|
混合声明:混合声明和代码。
|
C99。标准 C++。已实现。
|
属性扩展
|
__has_attribute() 可用于测试已识别的属性。有关更多信息,请参见 元素组属性。
|
函数原型:原型声明和旧风格定义。
|
仅在 C 中实现。与 C++ 无关。
|
C++ 注释:可识别。
|
已在 C 中实现。
|
美元符号:标识符中允许使用美元符号。
|
已实现。要求 –features=iddollar。
|
字符转义:‘\e’ 代表字符 <ESC>。
|
未实现。
|
对齐:查询类型或变量对齐。
|
C11,拼写为 _Alignof。C 和 C++ 中支持 __alignof__。C++ 在 C++11 模式下支持 alignof。
|
内联:定义内联函数(速度与宏一样快)。
|
C99 和标准 C++。已实现。GCC 实现该标准前,它会创建一个静态函数体而不是外部函数体。如果您的代码依赖于此,您可以使用 C 选项 –features=no%extinl 从 Oracle Developer Studio C 编译器获得类似的行为。
|
volatile:何种访问构成对 volatile 对象的访问。
|
已实现。与 GCC 兼容。
|
将汇编语言与 C 一起使用:供 C 与汇编程序进行交互的指令和扩展。
|
已实现。C 和 C++ 实现了 gcc-compatible asm() 语句,包括约束、asm() 标签和显式寄存器变量。
|
替代关键字:用于头文件的 __const__、__asm__ 等。
|
已实现。Oracle Developer Studio 12.5 C++ 添加了 __asm 和 __volatile 关键字拼写。
|
不完整的枚举:enum foo;,后面带有定义。
|
C++11。已在 C 和 C++ 中实现。必须为 C++11 模式。
|
函数名称:当前函数名称的可列显字符串。
|
Oracle Developer Studio compirs 支持 __func____FUNCTION__ 和 __PRETTY_FUNCTION__。
|
返回地址:获取函数的返回地址或帧地址。
|
未实现。
|
向量扩展:通过内置函数使用向量指令。
|
|
Offsetof:实现 offsetof 的特殊语法。
|
未实现。
|
__sync 内置函数:用于原子内存访问的传统内置函数。
|
已实现。使用 –xatomic=studio。请参见 原子。( gcc 弃用了这些函数,而是使用标准 __atomic 内置函数。)
|
__atomic 内置函数:带有内存模型的原子内置函数。
|
已实现。Oracle Developer Studio 12.5 中的新功能。使用 –xatomic=studio。请参见 原子。
|
整数溢出内置函数:执行算术检查和算术溢出检查的内置函数。
|
未实现。
|
用于事务处理内存的 x86 专用内存模型扩展:x86 内存模型。
|
未实现。
|
对象大小检查:用于受限缓冲区溢出检查的内置函数。
|
未实现。
|
指针边界检查程序内置函数:用于指针边界检查程序的内置函数。
|
未实现。
|
Cilk Plus 内置函数:用于 Cilk Plus 语言扩展的内置函数。
|
未实现。
|
其他内置函数:其他内置函数。
|
__builtin_constant_p() 可以测试某个项目是否为编译时常量。Oracle Developer Studio 尚未实现大多数其他内置函数。
|
目标内置函数:专用于特定目标的内置函数。
|
未实现。
|
目标格式检查:专用于特定目标的格式检查。
|
未实现。
|
Pragmas:gcc 接受的 Pragmas。
|
已实现 #pragma once。其他尚未实现。
|
未命名字段:结构/联合中的未命名结构/联合字段。
|
C++11。已在 C 和 C++ 中实现。
|
线程局部:每个线程的变量。
|
C99。C++11。已在 C 和 C++ 中实现。
|
二进制常量:使用 ‘0b’ 前缀的二进制常量。
|
仅在 C++ 中实现。
|
|
SIMD 向量支持
Oracle Developer Studio 支持某些特定于体系结构的内部函数通过使用特定于 CPU 的指令对向量操作进行编码。创建这些向量的数据类型时会使用 vector_size 属性或按头文件兼容性中所述加入相应的头文件。部分 C 运算符支持这些类型,但在某些情况下,您可能需要使用特定于 CPU 的内部函数。
有关 _m128 等类型以及对这些类型的操作的说明,请参见Oracle Developer Studio 12.5:C 用户指南 中的 SIMD 内部函数中的“SPARC64 X”一节。
C++ 专用功能
Oracle Developer Studio C++ 编译器支持 –features=cplusplus_redef 选项,该选项允许 __cplusplus 宏使用使用非标准值,以便用于需要该设置的源代码。Oracle Developer Studio 12.5:C++ 用户指南 中的 –xrestrict[=f]
C++ 的部分其他 GNU 扩展包括:
-
枚举中的 long long 常量
-
允许为 void 使用 typedef 作为函数参数
-
typedef void VOID;
int foo(VOID);
-
包括 <stdbool.h> 时,_Bool 等同于 Oracle Linux 上的 bool
-
extern 模板
-
long long 位字段
-
pragma pack push/pop
有关 C++ 扩展的信息,请参见 GCC 文档中的 C++ 语言的扩展。Oracle Developer Studio 编译器中相同功能的信息可在下表中找到。
表 2 GNU C++ 扩展
|
|
C++ Volatile:确定何种访问构成对 volatile 对象的访问。
|
兼容的实现。
|
受限指针:C99 受限指针和引用。
|
已实现。
|
Vague 链接:G++ 放置内联、vtable 等内容的位置。
|
Oracle Developer Studio 也为这些使用 COMDAT,但方法可能稍有不同。
|
C++ 接口:您可以同时为声明和定义使用单个 C++ 头文件。
|
未实现。在 gcc 中已弃用。
|
模板实例化:确保发出每个所需模板实例化的一份精确副本的方法。
|
Oracle Developer Studio 也为这些使用 COMDAT,但方法可能稍有不同。
|
绑定的成员函数:您可以提取一个指向由 ‘->*’ 或 ‘.*’ 表达式表示的方法的函数指针。
|
未实现。
|
C++ 属性:仅限 C++ 的变量、函数和类型属性。
|
|
函数多版本:声明多个函数版本。
|
未实现。
|
命名空间关联:使用命名空间关联指令的强关联。
|
未实现。在 gcc 中已弃用,取而代之的是标准 C++11 功能。
|
traits 类型:编译器支持 traits 类型。
|
未实现。
|
C++ 概念:改善了对通用编程的支持。
|
未实现。
|
Java 异常:调整异常处理,使其能与 Java 一起使用。
|
未实现。
|
已弃用的功能:计划从 C++ 中移除。
|
未实现。
|
向后兼容性:兼容早期的 C++ 定义。
|
未实现。
|
|
元素组属性
有关 Oracle Developer Studio 12.5 编译器中实现的属性的完整说明,请参见Oracle Developer Studio 12.5:C 用户指南 中的 支持的属性和Oracle Developer Studio 12.5:C++ 用户指南 中的 支持的属性。
__has_attribute() 内置函数可与 gcc 和 Oracle Developer Studio 编译器一起使用,从而测试已识别的属性。
下列属性是 Oracle Developer Studio 12.5 C++ 中新增的属性:aligned、deprecated、weak(alias)、weakref、packed、tls_model、vector_size 和 visibility。
Oracle Developer Studio 编译器不支持属性的所有语法。
表 3 GCC 属性
|
|
函数属性:声明函数没有副作用,或它们从不返回任何内容。
|
alias、aligned、always_inline、
const constructor/destructor、
deprecated (C++14)、malloc、noinline、noreturn、
nothrow(仅限 c++)、pure、returns_twice、visibility、
weak(和 alias)、weakref (C++)
|
变量属性:指定变量属性。
|
aligned、deprecated、mode (C++)、packed(部分实现)、tls_model、vector_size、weak
|
类型属性:指定类型属性。
|
aligned, deprecated, packed, visibility
|
枚举器属性:指定枚举器属性。
|
deprecated
|
|
命令行选项
Oracle Developer Studio 和 gcc 编译器都实现了传统的编译器选项,例如 –g、–c、–o 等。下表介绍了 Oracle Developer Studio 编译器专为与 gcc 兼容而实现的选项。
Oracle Developer Studio 中的以下选项与 gcc 兼容。
表 4 兼容选项
|
|
–std
|
–std 选项会选择语言标准,例如 C11、C++11 等。
|
–pedantic
|
违反本应接受的技术标准时发出错误或警告。此选项是 Oracle Developer Studio 12.5 C++ 编译器中的新增选项。
|
–m32 / –m64
|
选择 32 位或 64 位二进制输出。
|
–shared
|
生成共享库。在 Oracle Solaris Studio 12.4 中, –shared 选项所起的作用类似于 –G 的别名。在 Oracle Developer Studio 12.5 中,此选项所起的作用类似于 gcc 中的 –shared 选项。请参见 表 5。
|
|
以下选项在 Oracle Developer Studio 和 GCC 中的工作方式有所不同。
表 5 有差异的选项
|
|
|
–xM
|
–M
|
列显源文件的 make 风格依赖关系。在 gcc 中,–xM 会执行另一个函数。在 Oracle Developer Studio 中,–M 会选择链接程序映射文件。
|
–B(static| dynamic)
|
–Wl,–B(static| dynamic)
|
GNU 链接程序支持此行为,但 gcc 不支持。使用 –Wl 将选项传递给 GNU ld。在 gcc 中,–B 会执行另一个函数。
|
–G
|
–shared
|
生成共享库时,gcc 中的 –shared 会添加 C++ 库依赖关系。Oracle Developer Studio 编译器中的 –G 选项不会添加它们。
|
|
以下 gcc 风格的选项会自动转换为 Oracle Developer Studio 中的对应选项。要查看选项列表,请将此选项传递给 C 或 C++ 编译器的以下选项:–xhelp=gccflags。
表 6 自动转换的选项
|
|
–MM
|
与 –xM1 相同。
|
–Ofast
|
与 –fast 相同。
|
–Wall
|
与 +w2 相同(仅限 C++)
|
–Wall
|
与 –v 相同(仅限 C)
|
–Werror
|
与 –errwarn=%all 相同。
|
–Wpedantic
|
与 –pedantic 相同。
|
–fno-elimininate-unused-debug-types
|
接受并忽略
|
–fopenmp
|
与 –xopenmp 相同。
|
–fPIC
|
与 –KPIC 相同。
|
–fpic
|
与 –Kpic 相同。
|
–fplan9-extensions
|
接受并忽略(仅限 C)。
|
–fplugin-arg-name=t
|
警告并忽略(仅限 C)
|
–fplugin=t
|
警告并忽略(仅限 C)
|
–fsigned-char
|
与 –xchar=signed 相同(仅限 C)
|
–fsyntax-only
|
与 –xe 相同。
|
–funsigned-char
|
与 –xchar=unsigned 相同(仅限 C)
|
–gdwarf-version
|
与 –xdebugformat=dwarf 相同。
|
–gstabs
|
与 –xdebugformat=stabs 相同。
|
–gstabs+
|
建议使用 –xdebugformat=stabs;选项被忽略
|
–iplugindir=t
|
警告并忽略
|
–march=a
|
与 –xtarget= 相同 a
|
–mcpu=a
|
与 –xtarget= 相同 a
|
–mfmaf
|
与 –fma=fused 相同。
|
–mno-vis
|
与 –xvis=no 相同。
|
–mno-vis2
|
与 –xvis=no 相同。
|
–mno-vis3
|
与 –xvis=no 相同。
|
–mtune=a
|
与 –xtarget= 相同 a
|
–mvis
|
与 –xvis 相同。
|
–mvis2
|
与 –xvis 相同。
|
–mvis3
|
与 –xvis 相同。
|
–no-canonical-prefixes
|
接受并忽略
|
–no-fma
|
与 –fma=none 相同。
|
–no-fmaf
|
与 –fma=none 相同。
|
–no-trigraphs
|
与 –xtrigraphs=no 相同。
|
–nodefaultlibs
|
与 –xnolib 相同(仅限 C++)
|
–pass-exit-codes
|
警告并忽略
|
–pedantic-errors
|
与 –pedantic 相同。
|
–pipe
|
警告并忽略
|
–save-temps
|
与 –keeptmp 相同。
|
–shared
|
与 –G 相同。
|
–specs=t
|
警告并忽略
|
–traditional
|
与 –Xs 相同(仅限 C)
|
–trigraphs
|
与 –xtrigraphs=yes 相同。
|
|