| | |
main() 的 envp 参数
| 允许 envp 作为 main() 的第三个参数。
| 允许第三个参数;但是,该用法并不严格符合 ISO C 标准。
|
关键字
| 将标识符 const、volatile 和 signed 视为普通标识符。
| const、volatile 和 signed 是关键字。
|
块内部的 extern 和 static 函数声明
| 将这些函数声明提升为文件作用域。
| 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 成员的名称空间
| 允许 struct、union 和运算类型使用成员选择运算符 (’.’, ’->’) 处理其他 structs 或 unions 的成员。
| 要求各个唯一 struct/union 具有自己的唯一名称空间。
|
作为 lvalue 的强制类型转换
| 支持将整数类型和指针类型强制转换为 lvalue。例如: (char *)ip = &char;
| 不支持此功能。
|
隐含的 int 声明
| 支持不带显式类型说明符的声明。num; 等声明被视为隐含的 int。例如: num; /*num 隐含为 int*/ int num2; /* 显式声明 num2*/ /* declared an int */
| num; 声明(没有显式类型说明符 int)不受支持,会生成语法错误。
|
空声明
| 允许空声明,如: 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 中,因此在编译过程中不会直接调用 cpp(除了在 -Xs 模式中)。
|
使用反斜杠的行串联
| 不识别此上下文中的反斜杠字符。
| 要求换行符紧跟在反斜杠字符后面并拼接在一起。
|
文本字符串中的三字母
| 不支持此 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 功能。
|
|
预处理程序指令
| 支持两个 pragma unknown_control_flow 和 makes_regs_inconsistent 以及 #ident 指令。预处理程序发现无法识别的 pragma 时发出警告。
| 不指定预处理程序对无法识别的 pragma 的行为。
|
预定义的宏名称
| 未定义以下由 ISO C 定义的宏名称: __STDC__ __DATE__ __TIME__ __LINE__
|
|