假设函数参数将在堆栈上顺序传递是否安全?
例如,无论编译器设置如何,foo
都保证输出x y z
吗?
void foo(int x, int y, int z) {
int *vector = &x;
for(int i = 0; i < 3; i++) {
std::cout << vector[i] << " ";
}
}
我尝试使用visual studio并且它确实有效,但我不确定这种行为是否得到保证。
答案 0 :(得分:7)
无论编译器设置如何,您的程序都有未定义的行为。
您可以将&x
视为一个 int
数组的第一个元素的地址,因此vector[1]
和vector[2]
是越界数组访问。
答案 1 :(得分:5)
该语言不作出此保证。参数通常在堆栈和寄存器中传递,或者是组合。这取决于ABI和调用约定。
答案 2 :(得分:4)
简答:不。
长答案 - 每种处理器类型都有一组或多组与之关联的调用约定。这决定了通常如何传递参数 - 通常是寄存器和堆栈位置的某种组合。如果智能编译器/优化器知道有关上下文的信息,它可以在特定实例中覆盖这些约定,直到并且包括不传递(未使用的等)参数。 (这使得实施调试工具的人感到痛苦;-()
为了使事情更具体 - 普通英特尔处理器的约定取决于它们是以32位还是64位模式运行。
答案 3 :(得分:0)
换句话说,以这种方式编写 bug 。
(还有一个坏一个!)
这是头号规则,恕我直言:“说出你的意思。”不要试图聪明,高效或可爱。不要假设任何实施;不要试图为它做一个优化编译器的工作。为您的同事(以及您自己未来的自己)写的比计算机更多。此外,努力使您的代码可维护。“未来证明”。
如果这意味着,说“冗余地”,“低效率地”,“不优雅地”,写出“额外”的陈述来做一些可以“打结”成更少陈述的事情,“鲸鱼关心谁?” / em>(我们现在使用硬件可以每秒执行数十亿次操作。)人们唯一关心的是你的代码不起作用或什么时候破坏别的东西。
简单...... 人(!) ... 清晰度 ......是...... Key。写清楚,,你就不会出错。