Oracle® Developer Studio 12.5:C 用户指南

退出打印视图

更新时间: 2016 年 7 月
 
 

Oracle Developer Studio C:K&R C 和 ISO C 之间的差异

本附录介绍了以前的 K&R Oracle Developer Studio C 和 Oracle Developer Studio ISO C 之间的差异。

有关更多信息,请参见标准符合性

I.1 不兼容性

表 121  K&R C 与 ISO C 不兼容的内容
主题
Oracle Developer Studio C (K&R)
Oracle Developer Studio ISO C
main()envp 参数
允许 envp 作为 main() 的第三个参数。
允许第三个参数;但是,该用法并不严格符合 ISO C 标准。
关键字
将标识符 constvolatilesigned 视为普通标识符。
constvolatilesigned 是关键字。
块内部的 externstatic 函数声明
将这些函数声明提升为文件作用域。
ISO 标准不保证块作用域函数声明提升为文件作用域。
标识符
允许标识符中使用美元符号 ($)。
不允许使用 $
long float 类型
接受 long float 声明,并将这些声明视为 double
不接受这些声明。
多字符字符常量
int mc = ’abcd’;
结果:
abcd
int mc = ’abcd’;
结果:
dcba
整型常量
在八进制换码序列中接受 8 或 9。
在八进制换码序列中不接受 8 或 9。
赋值运算符
将以下运算符对视为两个标记,因此允许它们之间出现空白:
*=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
将它们视为单个标记,因此不允许它们之间出现空白。
表达式的无符号保留语义
支持无符号保留,即 unsigned char/short 转换为 unsigned int
支持值保留,即 unsigned char/short 会转换为 int
单/双精度计算
将浮点表达式的操作数提升为 double
声明以返回 float 的函数总是将其返回值提升为 double
允许在单精度计算中执行对 float 的操作。
允许这些函数具有 float 返回类型。
struct/union 成员的名称空间
允许 structunion 和运算类型使用成员选择运算符 (’.,->’) 处理其他 structsunions 的成员。
要求各个唯一 struct/union 具有自己的唯一名称空间。
作为 lvalue 的强制类型转换
支持将整数类型和指针类型强制转换为 lvalue。例如:
(char *)ip = &char;
不支持此功能。
隐含的 int 声明
支持不带显式类型说明符的声明。num; 等声明被视为隐含的 int。例如:
num; /*num 隐含为 int*/
int num2; /* 显式声明 num2*/
/* declared an int */
num; 声明(没有显式类型说明符 int)不受支持,会生成语法错误。
空声明
允许空声明,如:
int;
除标记之外,禁止空声明。
类型定义中的类型说明符
允许 typedef 声明中出现 unsignedshortlong 等类型说明符。例如:
typedef short small;
unsigned small x;
不允许类型说明符修改 typedef 声明。
位字段中允许的类型
允许所有整型的位字段,包括未命名位字段。
ABI 要求支持未命名位字段及其他整型。
只支持类型为 intunsigned intsigned int 的位字段。未定义其他类型。
不完全声明中标记的处理
忽略不完全类型声明。在以下示例中,f1 引用了外部 struct
struct x { . . . } s1;
{struct x; struct y {struct x f1; } s2; struct x
{ . . . };}
在符合 ISO 规范的实现中,不完全的 structunion 类型说明符会隐藏具有相同标记的封闭声明。
struct/union/enum 声明中的不匹配
允许嵌套的 struct/union 声明中标记的 struct/enum/union 类型出现不匹配。在以下示例中,第二个声明被视为 struct
struct x {. . . }s1;
{union x s2;. . .}
将内部声明视为新声明,隐藏外部标记。
表达式中的标签
将标签视为 (void *) lvalue
不允许在表达式中使用标签。
switch 条件类型
通过将 floatdouble 转换为 int,允许使用这两种类型。
对于 switch 条件类型,只对整型(int、char 和枚举类型)求值。
条件包含指令的语法
预处理程序会忽略 #else#endif 指令后的结尾令牌。
不允许此类构造。
标记粘贴和 ## 预处理程序运算符
不识别 ## 运算符。通过在粘贴的两个标记之间放置注释来完成标记粘贴:
#define PASTE(A,B) A/*任意注释*/B
## 定义为执行标记粘贴的预处理程序运算符,例如:
#define PASTE(A,B) A##B
此外,预处理程序无法识别该方法。相反,它将两个标记之间的注释视为空白。
预处理程序重新扫描
预处理程序递归替换:
#define F(X) X(arg)
F(F)
产生
arg(arg)
在重新扫描过程中,如果在替换列表中找到宏,则不替换宏:
#define F(X)X(arg)F(F)
结果:
F(arg)
形式参数列表中的 typedef 名称
您可以使用 typedef 名称作为函数声明中的正式参数名称。“隐藏”typedef 声明。
禁止使用声明为 typedef 名称的标识符作为形式参数。
特定于实现的聚集初始化
对括号中部分省略的初始化函数进行解析和处理时,使用自下而上的算法:
struct{ int a[3]; int b; }\ w[]={{1},2};
产生
sizeof(w)=16
w[0].a=1,0,0
w[0].b=2
使用自上而下的解析算法。例如:
struct{int a[3];int b;}\
w[]={{1},2};
产生
sizeof(w)=32w[0].a=1,0,0w[0].=0w[1].a=2,0,0w[1].b=0
include 文件的注释
允许在 #include 文件中开始的注释由包含第一个文件的文件终止。
在编译的转换阶段中注释被替换为空白字符,然后再处理 #include 指令。
字符常量中的形式参数替换
在字符常量与替换列表宏匹配时,替换字符常量中的字符:
#define charize(c)’c’
charize(Z)
结果:
’Z’
不替换字符:
#define charize(c) ’c’charize(Z)
结果:
’c’
字符串常量中的形式参数替换
字符串常量包含形式参数时,预处理程序替换形式参数:
#define stringize(str) ’str’
stringize(foo)
结果:
”foo”
应使用 # 预处理程序运算符:
#define stringize(str) ’str’
stringize(foo)
结果:
”str”
内置到编译器“前端”的预处理程序
编译器调用 cpp(1),然后调用编译系统的所有其他组件,具体取决于指定的选项。
包含预处理程序指令处理的 ISO C 转换阶段 1-4 会直接内置于 acomp 中,因此在编译过程中不会直接调用 cpp(除了在 -Xs 模式中)。
使用反斜杠的行串联
不识别此上下文中的反斜杠字符。
要求换行符紧跟在反斜杠字符后面并拼接在一起。
文本字符串中的三字母
不支持此 ISO C 功能。
asm 关键字
asm 是关键字。
asm 视为普通标识符。
标识符的链接
不将未初始化的 static 声明视为暂定声明。因此,第二个声明将生成“重新声明”错误,如下所示:
static int i = 1;
static int i;
将未初始化的 static 声明视为暂定声明。
名称空间
只分为三类:struct/union/enum 标记、struct/union/enum 的成员及其他。
识别四种不同的名称空间:标签名称、标记(跟在关键字 struct、unionenum 后面的名称)、struct/union/enum 的成员以及普通标识符。
long double 类型
不支持。
允许 long double 类型声明。
浮点常量
浮点后缀 flFL 不受支持。
无后缀整型常量可以具有不同的类型
不支持整型常量后缀 u 和 U
宽字符常量
不接受宽字符常量的 ISO C 语法,如下所示:
wchar_t wc = L’x’;
支持此语法。
’\a’’\x’
将它们视为字符 ’a’ 和 ’x’。
'\a''\x' 视为特殊换码序列。
文本字符串的串联
不支持相邻文本字符串的 ISO C 串联。
宽字符文本字符串语法
不支持此示例中所示的 ISO C 宽字符文本字符串语法:
wchar_t *ws = L"hello";
支持此语法。
指针: void *char *
支持 ISO C void * 功能。
一元加运算符
不支持此 ISO C 功能。
函数原型-省略号
不支持。
ISO C 定义使用省略号 "..." 表示变量参数列表。
类型定义
禁止另一个具有相同类型名称的声明在内部块中重新声明 typedef
允许另一个具有相同类型名称的声明在内部块中重新声明 typedef
extern 变量的初始化
不支持显式声明为 extern 的变量的初始化。
将显式声明为 extern 的变量的初始化视为定义。
聚集的初始化
不支持联合或自动结构的 ISO C 初始化。
原型
不支持此 ISO C 功能。
预处理指令的语法
仅识别第一列中具有 # 的指令。
ISO C 允许在 # 指令前使用前导空白字符。
# 预处理程序运算符
不支持 ISO C # 预处理程序运算符。
#error 指令
不支持此 ISO C 功能。
预处理程序指令
支持两个 pragma unknown_control_flowmakes_regs_inconsistent 以及 #ident 指令。预处理程序发现无法识别的 pragma 时发出警告。
不指定预处理程序对无法识别的 pragma 的行为。
预定义的宏名称
未定义以下由 ISO C 定义的宏名称:
__STDC__
__DATE__
__TIME__
__LINE__