问题描述
过去,我已经开发了嵌入式系统的项目,我们重新排列了堆栈变量的声明顺序,以减少生成的可执行文件的大小。例如,如果我们有:
I have worked on projects for embedded systems in the past where we have rearranged the order of declaration of stack variables to decrease the size of the resulting executable. For instance, if we had:
void func()
{
char c;
int i;
short s;
...
}
我们会将其重新排序为: p>
We would reorder this to be:
void func()
{
int i;
short s;
char c;
...
}
由于对齐问题, 12字节的堆栈空间被使用,第二个只产生了8个字节。
Because of alignment issues the first one resulted in 12 bytes of stack space being used and the second one resulted in only 8 bytes.
这是C编译器的标准行为还是我们使用的编译器的缺点?
Is this standard behavior for C compilers or just a shortcoming of the compiler we were using?
在我看来,编译器应该能够重新排序堆栈变量,以便更小的可执行文件大小。有人建议我,C标准的某些方面阻止了这一点,但我还没有能够找到一个有信誉的来源,无论哪种方式。
It seems to me that a compiler should be able to reorder stack variables to favor smaller executable size if it wanted to. It has been suggested to me that some aspect of the C standard prevents this, but I haven't been able to find a reputable source either way.
作为一个奖金问题,这是否也适用于C ++编译器?
As a bonus question, does this also apply to C++ compilers?
编辑
是的,C / C ++编译器可以重新排列堆栈变量,你能给一个编译器的例子绝对这样做吗?
If the answer is yes, C/C++ compilers can rearrange stack variables, can you give an example of a compiler that definitely does this? I'd like to see compiler documentation or something similar that backs this up.
再次编辑
感谢大家的帮助。对于文档,我能找到的最好的东西是(pdf)。
Thanks everybody for your help. For documentation, the best thing I've been able to find is the paper Optimal Stack Slot Assignment in GCC(pdf), by Naveen Sharma and Sanjiv Kumar Gupta, which was presented at the GCC summit proceedings in 2003.
这里的问题是使用ADS编译器进行ARM开发。在该编译器的文档中提到,像我所示的排序声明可以提高性能以及堆栈大小,因为ARM-Thumb架构计算本地堆栈帧中的地址。该编译器没有自动重新排列本地人以利用这一点。在这里链接的文章说,从2003年GCC也没有重新排列堆栈框架,以提高ARM-Thumb处理器的参考位置,但它意味着你可以。
The project in question here was using the ADS compiler for ARM development. It is mentioned in the documentation for that compiler that ordering declarations like I've shown can improve performance, as well as stack size, because of how the ARM-Thumb architecture calculates addresses in the local stack frame. That compiler didn't automatically rearrange locals to take advantage of this. The paper linked here says that as of 2003 GCC also didn't rearrange the stack frame to improve locality of reference for ARM-Thumb processors, but it implies that you could.
我找不到任何肯定说这是在GCC实现,但我认为这篇文章证明你都是正确的。再次感谢。
I can't find anything that definitely says this was ever implemented in GCC, but I think this paper counts as proof that you're all correct. Thanks again.
推荐答案
由于标准中没有任何内容禁止C或C ++编译器, 。
As there is nothing in the standard prohibiting that for C or C++ compilers, yes, the compiler can do that.
它对于聚合(即结构)是不同的,其中必须保持相对顺序,但是编译器仍然可以插入填充字节以实现优选的对齐。
It is different for aggregates (i.e. structs), where the relative order must be maintained, but still the compiler may insert pad bytes to achieve preferable alignment.
IIRC较新的MSVC编译器在对抗本地缓冲区溢出时使用这种自由。
IIRC newer MSVC compilers use that freedom in their fight against buffer overflows of locals.
,在C ++中,破坏的顺序必须是相反的顺序,即使编译器重新排序内存布局。
As a side note, in C++, the order of destruction must be reverse order of declaration, even if the compiler reorders the memory layout.
(我不能引用章节和,这是来自内存。)
(I can't quote chapter and verse, though, this is from memory.)
这篇关于C编译器可以重排栈变量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!