一个有趣的问题;我自己也犯了这个罪;主要是由于涉及对无辜内存块的可疑类型强制转换的可怕黑客攻击。
这个答案实际上只是R 的答案的必然结果,这几乎解决了这个问题(尽管我不太确定这and goes out of scope after that function ends..
一点)
对我来说,关键是阅读:
(1)ISO C99 6.7.2:
如果它们的类型相同,则两种类型具有兼容的类型。用于确定两种类型是否兼容的附加规则在 6.7.2 中针对类型说明符、在 6.7.3 中针对类型限定符以及在 6.7.5 中针对声明符进行了描述。46) 此外,两个结构、联合或枚举类型分别声明如果翻译单元的标签和成员满足以下要求,则翻译单元是兼容的:如果一个用标签声明,另一个应该用相同的标签声明。...
(2) C 命名空间
无论如何,这里有一些代码(~几个翻译单元),希望为那些以前没有遇到过这个问题的人展示一些可能令人惊讶的行为:
废话.c:
#include <stdio.h>
struct bar {int a; int b;} stbar;
struct bar_ {int a; int d;} stbar_;
void foo(struct bar* pst);
void foo_(struct bar st);
void callfoo()
{
/*no warnings; possibly surprising results ! */
stbar.a=313;
stbar.b=31313;
foo(&stbar);
printf("called foo() with stbar: %d, %d\n", stbar.a, stbar.b);
/*generates incompatible types warnings:
blah.c:23:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar_ *’ */
stbar_.a=313;
stbar_.d=31313;
foo(&stbar_);
printf("called foo() with stbar_: %d, %d\n", stbar_.a, stbar_.d);
/*generates incompatible types warnings:
blah.c:31:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar *’ */
struct bar {float s; float t;} stbar;
foo(&stbar);
printf("called foo() with locally defined stbar: %f, %f\n", stbar.s, stbar.t);
}
void callfoo_()
{
stbar.a=313;
stbar.b=31313;
//passing in incompatible type by value ~ no warnings; possibly surprising results !
foo_(stbar);
/*uncomenting next line generates compiler error:
blah.c:47:5: error: incompatible type for argument 1 of ‘foo_’
blah.c:7:6: note: expected ‘struct bar’ but argument is of type ‘struct bar_’ */
//foo_(stbar_);
}
void main()
{
callfoo();
callfoo_();
}
废话_.c:
#include <stdio.h>
struct bar {int x; float z;} stbar;
void foo(struct bar* pst)
{
printf("foo : %d, %f\n", pst->x, pst->z);
pst->x=13;
pst->z=13.13;
}
void foo_(struct bar st)
{
printf("foo_ : %d, %f\n", st.x, st.z);
st.x=13;
st.z=13.13;
}
输出:
$ gcc blah.c blah_.c
blah.c: In function ‘callfoo’:
blah.c:23:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar_ *’
blah.c:31:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar *’
$ ./a.out
foo : 313, 0.000000
called foo() with stbar: 13, 1095898235
foo : 313, 0.000000
called foo() with stbar_: 13, 1095898235
foo : 13274075, 0.000000
called foo() with locally defined stbar: 0.000000, 13.130000
foo_ : 313, 0.000000
$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 ...
推论的推论:赞美神为C++ namespace
。