理解C中的数组声明
我试图理解C标准是如何解释声明可能导致错误的。考虑下面的非常简单的代码:理解C中的数组声明,c,arrays,declaration,C,Arrays,Declaration,我试图理解C标准是如何解释声明可能导致错误的。考虑下面的非常简单的代码: int main() { char test[1024 * 1024 * 1024]; test[0] = 0; return 0; } 这是赛格鲁兹。但以下代码不适用: int main() { char test[1024 * 1024 * 1024]; return 0; } 但是当我在我的机器上编译它时,最新的一个也出现了故障。主要功能如下所示 00000000000
int main()
{
char test[1024 * 1024 * 1024];
test[0] = 0;
return 0;
}
这是赛格鲁兹。但以下代码不适用:
int main()
{
char test[1024 * 1024 * 1024];
return 0;
}
但是当我在我的机器上编译它时,最新的一个也出现了故障。主要功能如下所示
00000000000008c6 <main>:
8c6: 55 push %rbp
8c7: 48 89 e5 mov %rsp,%rbp
8ca: 48 81 ec 20 00 00 40 sub $0x40000020,%rsp
8d1: 89 bd ec ff ff bf mov %edi,-0x40000014(%rbp) // <---HERE
8d7: 48 89 b5 e0 ff ff bf mov %rsi,-0x40000020(%rbp)
8de: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
8e5: 00 00
8e7: 48 89 45 f8 mov %rax,-0x8(%rbp)
8eb: 31 c0 xor %eax,%eax
8ed: b8 00 00 00 00 mov $0x0,%eax
8f2: 48 8b 55 f8 mov -0x8(%rbp),%rdx
8f6: 64 48 33 14 25 28 00 xor %fs:0x28,%rdx
8fd: 00 00
8ff: 74 05 je 906 <main+0x40>
901: e8 1a fe ff ff callq 720 <__stack_chk_fail@plt>
906: c9 leaveq
907: c3 retq
908: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
90f: 00
0000000000000 8c6:
8c6:55%推送rbp
8c7:48 89 e5 mov%rsp,%rbp
8ca:48 81 ec 20 00 00 40 sub$0x40000020,%rsp
8d1:89 bd ec ff bf mov%edi,-0x40000014(%rbp)/结果取决于实现
我可以想出几个原因来解释为什么行为会有所不同
- 编译器发现变量没有被使用,没有可能的副作用,并对其进行优化(即使没有优化级别)
- 根据请求调整堆栈大小。既然还没有写入这个变量,为什么现在要调整堆栈的大小
- 编译器不必将堆栈用于自动内存。编译器可以使用
malloc
分配内存,并在退出时释放内存。使用heap将允许分配1Gb而不会出现问题
- 堆栈大小设置为1Gb:)
不同级别的优化?尝试使用-O2
@KeineLust编译。在我的机器上编译时,我没有指定任何优化标志,在本演示中也没有指定。只需gcc-cmain.c
@KeineLustO2
就可以了,谢谢。但不管怎样,对这种行为的正式解释如何?最好能在标准中找到一些参考资料。这是定义的行为,不是吗?是的,我就是这么说的,也许Coliru在编译时进行了某种程度的优化,跳过了整个程序。不,标准没有说自动内存使用堆栈。一些编译器可以在堆上分配内存(这会起作用),并最终释放内存。并且优化它(即使没有优化级别),这一点很好!无volatile
no party:P