当以下代码中没有struct bar
的可见声明或定义时,它会成功编译为C ++但不能编译为C:
void foo(struct bar* p);
void foo(struct bar* p){}
int main(){}
编译为C时出现错误消息:error: conflicting types for 'foo'
。
任何人都可以解释这种行为吗?
我对clang++ 3.4和g++ 4.8.2 -Wall -Wextra -pedantic-errors
标记以及-std=c99
或-std=c++03
分别对C和C ++进行了尝试。
答案 0 :(得分:10)
让我们通过省略声明和无用的main
:
void foo(struct bar* p){}
编译器看到struct bar
,但尚未定义。 GCC 4.8.2的错误消息说明了它的下一步:
a.c:1:17: warning: ‘struct bar’ declared inside parameter list [enabled by default]
void foo(struct bar* p){}
^
a.c:1:17: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
所以现在假设struct bar
只存在于foo
的定义中。但是,代码编译得很完美。
添加函数原型时:
void foo(struct bar* p);
void foo(struct bar* p){}
警告变为:
a.c:1:17: warning: ‘struct bar’ declared inside parameter list [enabled by default]
void foo(struct bar* p);
^
a.c:1:17: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
a.c:3:17: warning: ‘struct bar’ declared inside parameter list [enabled by default]
void foo(struct bar* p){}
^
a.c:3:6: error: conflicting types for ‘foo’
void foo(struct bar* p){}
^
a.c:1:6: note: previous declaration of ‘foo’ was here
void foo(struct bar* p);
^
与之前一样,编译器为原型组成一个新的未定义类型struct bar
,为函数定义组成另一个 。因此foo
的原型及其定义引用了不同的类型,都命名为struct bar
。它们不匹配,因此错误。
解决方案是先向前声明struct
:
struct bar;
void foo(struct bar* p);
void foo(struct bar* p){}
此编译没有警告。