|
|
|
main() 的 envp 参数 |
允许 envp 作为 main() 的第三个参数。 |
允许第三个参数;但是,该用法并不严格符合 ISO C
标准。 |
关键字 |
将标识符 const、volatile 和 signed 视为普通标识符。 |
const、volatile 和 signed 是关键字。 |
块内部的 extern 和 static 函数声明 |
将这些函数声明提升为文件作用域。 |
ISO
标准不保证块作用域函数声明提升为文件作用域。 |
标识符 |
允许标识符中使用美元符号 ($)。 |
不允许使用 $。 |
long float 类型 |
接受 long float 声明,并将这些声明视为 double。 |
不接受这些声明。 |
多字符字符常量 |
|
|
整型常量 |
在八进制换码序列中接受 8 或 9。 |
在八进制换码序列中不接受 8 或
9。 |
赋值运算符 |
将以下运算符对视为两个标记,因此允许它们之间出现空白: *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= |
将它们视为单个标记,因此不允许它们之间出现空白。 |
表达式的无符号保留语义 |
支持无符号保留,即 unsigned char/short 转换为 unsigned int。 |
支持值保留,即 unsigned char/short 转换为 int。 |
单/双精度计算 |
将浮点表达式的操作数提升为 double。 声明以返回 float 的函数总是将其返回值提升为 double。 |
允许在单精度计算中执行对 float
的操作。 允许这些函数具有 float 返回类型。 |
struct/union 成员的名称空间 |
允许使用成员选择运算符(’.’、’->’)的 struct、union 和算术类型处理其他 struct 或 union 的成员。 |
要求各个唯一 struct/union 具有自己的唯一名称空间。 |
作为
lvalue 的强制类型转换 |
支持将整数类型和指针类型强制转换为 lvalue。例如: (char *)ip = &char; |
不支持此功能。 |
隐含的 int 声明 |
支持不带显式类型说明符的声明。 num; 等声明被视为隐含的 int。例如: num; /*num 隐含为 int*/ int num2; /* 显式声明 num2*/ /* declared an int */ |
不支持 num; 声明(不带显式类型说明符 int),生成语法错误。 |
空声明 |
|
除标记之外,禁止空声明。 |
类型定义中的类型说明符 |
允许 typedef 声明中出现
unsigned、 short、 long 等类型说明符。例如: typedef short small; unsigned small x; |
不允许类型说明符修改 typedef 声明。 |
位字段中允许的类型 |
允许所有整型的位字段,包括未命名位字段。 ABI 要求支持未命名位字段及其他整型。 |
只支持类型为 int、unsigned int 和 signed int 的位字段。未定义其他类型。 |
不完全声明中标记的处理 |
忽略不完全类型声明。在以下示例中, f1 是指外部 struct: struct x { . . . } s1; {struct x; struct y {struct x f1; } s2; struct x { . . . };} |
在符合 ISO
的实现中,不完整的 struct 或 union 类型说明符将隐藏具有相同标记的封闭声明。 |
struct/union/enum 声明中的不匹配 |
允许嵌套的 struct/union 声明中标记的 struct/enum/union 类型出现不匹配。在以下示例中,第二个声明被视为 struct: struct x {. .
. }s1; {union x s2;. . .} |
将内部声明视为新声明,隐藏外部标记。 |
表达式中的标签 |
将标签视为 (void *) lvalue。 |
不允许在表达式中使用标签。 |
switch 条件类型 |
通过将 float 和 double 转换为 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 中,因此除了在
-Xs 模式下之外,编译时不直接调用 cpp。 |
使用反斜杠的行串联 |
不识别此上下文中的反斜杠字符。 |
要求换行符紧跟在反斜杠字符后面并拼接在一起。 |
文本字符串中的三字母 |
不支持此 ISO C 功能。 |
|
asm 关键字 |
asm 是关键字。 |
将 asm 视为普通标识符。 |
标识符的链接 |
不将未初始化的 static 声明视为暂定声明。因此,第二个声明将生成“重新声明”错误,如下所示: static int i = 1; static int i; |
将未初始化的
static 声明视为暂定声明。 |
名称空间 |
只分为三类:struct/union/enum 标记、struct/union/enum 的成员及其他。 |
识别四种不同的名称空间:标签名称、标记(跟在关键字 struct、union 或 enum 后面的名称)、struct/union/enum 的成员以及普通标识符。 |
long double 类型 |
不支持。 |
允许 long double 类型声明。 |
浮点常量 |
不支持浮点后缀
f、l、F 和 L。 |
|
无后缀整型常量可以具有不同的类型 |
不支持整型常量后缀 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 功能。 |
|
预处理程序指令 |
支持 unknown_control_flow 和 makes_regs_inconsistent 两个 pragma 以及 #ident 指令。预处理程序发现无法识别的
pragma 时发出警告。 |
不指定预处理程序对无法识别的 pragma 的行为。 |
预定义宏名称 |
未定义以下由 ISO C 定义的宏名称: __STDC__ __DATE__ __TIME__ __LINE__ |
|