C语言特性

clang中对于标准C的支持是全部特性的,除了C99浮点附注。

clang支持的扩展

见于 Clang 语言扩展

各个标准模式之间的差异

clang支持-std选项,它改变clang使用的语言模式。支持的C语言模式有 c89, gnu89, c94, c99, gnu99 和 其他这些模式的别名。如果没有指定-std选项,默认的是gnu99模式。

所有c*和gnu*模式之间的区别:

  • c*模式定义了“STRICT_ANSI”。
  • 指定目标定义定义没有前置下划线,像”linux”,被定义在gnu* 模式中。
  • gnu* 模式中,Trigaphs模式是关闭的;它们可以被-trigraphs选项使能。
  • 在gnu* 模式中,解析器识别 “asm” 和 “typeof” 作为关键字;变体 “asm” and “typeof” 在所有模式中均被识别。
  • 在一些平台上的 gnu* 模式中,Apple 的 “blocks” 扩展被识别;也可以通过 “-fblocks” 选项在任何模式中使能。
  • 按照标准,数组是VLA,但是可以通过前端被常量折叠作为固定大小数组。这发生在例如 “int X[(1, 2)];”,技术上是VLA。c*模式严格顺从并把它们作为VLA。

*89 and *99 模式之间的区别:

  • *99模式默认实现了C99中指定的“inline”,而 *89 模式实现GNU 版本。这对于单个函数可以使用 gnu_inline 属性重载。
  • Digraphs在c89模式中不被识别。
  • “for”, “if”, “switch”, “while”, 或者 “do” 语句中定义的名称范围不同。(例如:“if ((struct x {int x;}*)0) {}”.)
  • *89中 STDC_VERSION 未被定义。
  • c89中“inline”不被识别为关键字。
  • *89 模式中不识别“restrict”作为关键字。
  • *99 模式中可以使用逗号在数字常量表达式中。
  • *89 模式中,不是左值的数组未被不明显的引进
  • 一些警告不同。

c94 模式和 c89 模式是相同的,除了digraphs在c94模式中被使能 (FIXME: 并且 STDC_VERSION 应当被定义!).

尚未实现的GCC扩展

clang尝试与gcc尽可能的兼容,但是一些gcc扩展还未实现:

  • clang不支持#pragma weak(bug 3679)。由于在bug中描述的使用,这很可能在某刻被实现,至少是部分上。
  • clang不支持十进制浮点类型 (_Decimal32 and 同类)或者定点类型(_Fract and 同类);还没有人表现出对这些特性的兴趣,所以还很难说它们什么时候会被实现。
  • clang不支持函数嵌套;这是一个不经常使用的复杂特性,所以它可能不会在近期实现。在C++11中,可以通过赋值lambda函数给局部变量来仿真,例如:
  1. auto const local_function = [&]($int parameter) {
  2. // Do something
  3. };
  4. ...
  5. local_function(1);
  • clang不支持全局寄存器变量;这不太可能很快实现,因为它需要附加的LLVM后端支持。
  • clang不支持可变数组成员静态初始化。这是一个不常用的扩展,但是可以根据用户需求实现。
  • clang不支持builtin_va_arg_pack/builtin_va_arg_pack_len。这个很少使用,但是在一些有意思的地方,例如glibc头文件,所以可能会根据用户需求实现。注意因为clang假装像GCC 4.2,并且这个扩展是4.3引进的,glibc头文件将不会在此刻尝试使用clang的这个扩展。
  • clang不支持gcc的函数参数向前声明扩展;这个还没有在实际代码中使用,所以它可能永远也不会被实现。

这个不是完全列表;如果你在这个表中找到丢失了一个不支持的扩展;请发邮件到cfe-dev。这张表暂时不包含C++;见C++ 语言特性。同样的,这张表也不包含大部分实现的扩展的bug;请参见bug tracker找已知bug(FIXME:有一节是关于bug报告的吗?)

故意不支持的GCC扩展

  • clang不支持结构体具有变长数组的gcc扩展。这个有好几个理由:一,它的实现比较微妙,二,这个扩展是完全没有文档的,三,这个扩展很少被使用。注意clang不支持可变数组成员(出于一个结构体末尾的具有0长或者未指定长度的数组)。
  • clang没有一个等价于gcc的”fold”;这意味着clang不接受一些gcc可能在上下文中接受的概念,那里就需要一个常量表达式。像”x-x”,x是变量。
  • clang不支持__builtin_apply和其同类;这个扩展着实难以可信的实现。

Microsoft扩展

clang对于Microsoft Visual C++具有一些实验性的支持;使用命令行选项 -fms-extensions 来开启。这对于 Windows 目标是默认的。注意支持是不完全的;使能 Microsoft 扩展将会默默的丢掉特定构建(包含__declspec和Microsoft-type 汇编语句)。

clang具有一个 -fms-compatibility 标志使得clang接受足够的非有效C++来解析大多数Microsoft头文件。这个标志对于 Windows 默认是开启的。

-fdelayed-template-parsing 让clang延迟所有模板实例化直到一个翻译单元结尾。这个对于 Windows 目标默认是开启的。

  • clang允许使用-fmsc-version=设置 _MSC_VER。默认为1300,和 Visual C/C++ 2003相同。可以使用任何数字并且可以很大的影响clang可以编译的Windows SDK和c++stdlib 头文件。这个选项将会被移除,当clang支持MS扩展的头文件全集。
  • clang不支持Microsoft 的匿名记录成员可以使用用户定义类型被声明的扩展。
  • clang支持 Microsoft “#pragma pack” 特性来控制记录布局。GCC 也包含对此项特性的支持,然而 MSVC 和 GCC 是不兼容的, clang 跟随 the MSVC 定义.
  • clang对于 Windows 目标默认到C++11。