Kyl*_*yle 9 c compiler-errors clang restrict c11
这将是一个长期的语言律师问题,所以我想快速说明为什么我发现它是相关的.我正在开展一个严格的标准合规性至关重要的项目(编写一种编译成C的语言).我要提供的示例似乎是clang部分的标准违规,因此,如果是这种情况,我想确认一下.
gcc说,带有指向限定限定指针的指针的条件不能与带有void指针的条件语句共存.另一方面,clang编译好的东西.这是一个示例程序:
#include <stdlib.h>
int main(void){
int* restrict* A = malloc(8);
A ? A : malloc(8);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于GCC,选项-std=c11和-pedantic可包括或不以任何组合,同样地对于铛和选项-std=c11和-Weverything.在任何情况下,clang编译没有错误,gcc给出以下内容:
tem-2.c: In function ‘main’:
tem-2.c:7:2: error: invalid use of ‘restrict’
A ? A : malloc(8);
^
Run Code Online (Sandbox Code Playgroud)
关于条件陈述,c11标准说明如下,强调增加:
6.5.15条件运算符
...
- 下列之一应适用于第二和第三操作数:
- 两个操作数都有算术类型;
- 两个操作数具有相同的结构或联合类型;
- 两个操作数都有空洞类型;
- 两个操作数都是兼容类型的限定或非限定版本的指针;
- 一个操作数是指针,另一个是空指针常量; 要么
- 一个操作数是指向对象类型的指针,另一个是指向合格或非限定版本的void的指针.
...
- 如果第二个和第三个操作数都是指针,或者一个是空指针常量而另一个是指针,则结果类型是指向使用两个操作数引用的类型的所有类型限定符限定的类型的指针.此外,如果两个操作数都是兼容类型的指针或兼容类型的不同限定版本,则结果类型是指向复合类型的适当限定版本的指针; 如果一个操作数是空指针常量,则结果具有另一个操作数的类型; 否则,一个操作数是指向void的指针或void的限定版本,在这种情况下,结果类型是指向适当限定版本的void的指针.
...
我看到它的方式,上面的第一个粗体部分表示两种类型可以一起使用,第二个粗体部分将结果定义为指向限制限定版本的void的指针.但是,如下所示,此类型不能存在,因此表达式被gcc正确识别为错误:
6.7.3类型限定词,第2段
引用类型为对象类型的指针类型以外的类型不应受限制.
现在,问题是这个示例程序违反了"不应该"的条件,因此需要通过以下方式产生错误:
5.1.1.3诊断,第1段
如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现 - 定义.在其他情况下不需要产生诊断消息.
通过静默处理错误类型,似乎clang不符合标准.这让我想知道铿锵有什么其他的默默无闻.
我在x86-64 Ubuntu机器上使用gcc版本5.4.0和clang版本3.8.0.
是的,它看起来像一个bug.
你的问题更简单:可以void将restrict合格吗?由于void显然不是指针类型,答案是否定的.因为这违反了约束,编译器应该提供诊断.
我能够clang通过使用_Generic表达来欺骗自己的罪
puts(_Generic(A ? A : malloc(8), void* : "void*"));
Run Code Online (Sandbox Code Playgroud)
并clang告诉我
static.c:24:18: error: controlling expression type 'restrict void *' not compatible with any generic association type
puts(_Generic(A ? A : malloc(8), void* : "void*"));
Run Code Online (Sandbox Code Playgroud)
这表明clang这里真的试图匹配一个废话类型restrict void*.
请向他们提交错误报告.