Job*_*lle 6 c pointers c99 parameter-passing c11
我想知道以下C代码是否符合C99和/或C11标准:
void foo(int bar0, int bar1, int bar2) {
int *bars = &bar0;
printf("0: %d\n1: %d\n2: %d\n", bars[0], bars[1], bars[2]);
}
int main(int argc, char **argv) {
foo(8, 32, 4);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在使用visual studio 2013并打印时,此代码段按预期编译和运行:
0:8
1:32
2:4
Sou*_*osh 11
不,不在附近.
C标准不保证函数参数存储在连续的内存位置(或者,任何特定的顺序,就此而言).由编译器和/或平台(体系结构)决定如何将函数参数传递给函数.
为了进一步增加清晰度,甚至不能保证要传递的参数存储在存储器(例如,堆栈)中.对于部分或全部参数,他们也可以使用硬件寄存器(适用时),以便快速进行操作.例如,
PowerPC的
PowerPC体系结构具有大量寄存器,因此大多数函数可以将寄存器中的所有参数传递给单级调用.[...]
MIPS
最常用的32位MIPS调用约定是O32 ABI,它将前四个参数传递给寄存器中的函数
$a0-$a3; 后续参数在堆栈上传递.[...]
X86
x86体系结构与许多不同的调用约定一起使用.由于架构寄存器数量较少,x86调用约定主要在堆栈上传递参数,而返回值(或指向它的指针)在寄存器中传递.
所以,你的情况,bars[0]是一种有效的访问,但是否bars[1]和bars[2]有效,取决于基础环境(平台/编译)完全.最好不要依赖你期望的行为.
也就是说,只是为了挑剔,如果你不打算使用传递的参数(如果有的话)main(),你可以简单地将签名减少到int main(void) {.
不,它不遵守任何已发布的标准.如何存储参数和局部变量,以及编译器的位置.在一个编译器中可能起作用的可能在另一个编译器中不起作用,或者甚至在同一编译器的不同版本上起作
C规范甚至没有提到堆栈,它指定的都是范围规则.