我使用gcc的-O
优化选项在我的一个项目模块中得到“虚拟内存耗尽:无法分配内存”错误。如果从命令行中删除-O
,则错误消失。
我检查了gcc规范,发现-O
-fauto-inc-dec
-fcompare-elim
-fcprop-registers
-fdce
-fdefer-pop
-fdelayed-branch
-fdse
-fguess-branch-probability
-fif-conversion2
-fif-conversion
-fipa-pure-const
-fipa-profile
-fipa-reference
-fmerge-constants
-fsplit-wide-types
-ftree-bit-ccp
-ftree-builtin-call-dce
-ftree-ccp
-ftree-ch
-ftree-copyrename
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-forwprop
-ftree-fre
-ftree-phiprop
-ftree-slsr
-ftree-sra
-ftree-pta
-ftree-ter
-funit-at-a-time
我的新命令行现在添加了以下选项
-fauto-inc-dec -fdce -fdefer-pop -fdse -fguess-branch-probability -fif-conversion2 -fif-conversion -fipa-pure-const -fipa-reference -fmerge-constants -fsplit-wide-types -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-phiprop -ftree-sra -ftree-pta -ftree-ter -funit-at-a-time -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector -fno-var-tracking -fno-var-tracking-assignments
但我无法重现此问题。
我正在使用的gcc版本无法识别某些选项(我已将其从命令行中删除)
gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/i686-redhat-linux/4.5.1/lto-wrapper
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.5.1 20100924 (Red Hat 4.5.1-4) (GCC)
任何人都可以知道可能出现的问题吗?
由于
P.S:我正在尝试编译的代码中存在大量STL内容。
答案 0 :(得分:1)
您可能希望获得特定编译器正在使用的完全优化选项的列表。它们可能因编译器而异,也可能因目标而异。
使用-Q
和--help=optimizers
可以为您提供帮助。例如,让我们假设您使用以下命令进行编译(并创建损坏的代码):
gcc -march=armv7-a -mfloat-abi=softfp -mthumb -std=c++11 -FPIC -DNDEBUG -I. -g -c myfile.cpp
如果此命令创建工作代码:
gcc -march=armv7-a -mfloat-abi=softfp -mthumb -std=c++11 -FPIC -DNDEBUG -O -I. -g -c myfile.cpp
您可以通过在命令开头添加-Q
并在结尾添加--help=optimizers
来获得不同的选项。对于破碎的命令:
gcc -Q -march=armv7-a -mfloat-abi=softfp -mthumb -std=c++11 -FPIC -DNDEBUG -I. -g -c myfile.cpp --help=optimizers > broken-opts
和工作人员:
gcc -Q -march=armv7-a -mfloat-abi=softfp -mthumb -std=c++11 -FPIC -DNDEBUG -O -I. -g -c myfile.cpp --help=optimizers > working-opts
查找标记为" [enabled]
"的选项在broken-opts
文件中但是" [disabled]
"在working-opts
文件中:
diff broken-opts working-opts | grep '<'
然后,您可以a)使用-O
进行编译并一次性禁用选项(即-fno-option-name
为-foption-name
选项),直到找到正确的选项为止一个要禁用,或者你可以b)编译而没有任何优化标志,并一次一个地添加选项,直到你找到&#34;破坏&#34;选项。
我用&#34;破坏&#34;带引号的选项 - 因为在我曾经处理的每个案例中,它实际上是 MY 代码的问题,并且编译器或优化器没有问题本身。但是,这个过程帮助我很多时候弄清楚我的代码中的问题所在(即,如果&#34;破坏&#34;选项与堆栈有关,或者与虚函数有关,你可以缩小搜索违规代码的范围。)