top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

gcc: difference -g -O1 vs. -O1

0 votes

If I compile my embedded program with options "-g -O1" I obtain an elf file with debug information. I can objcopy the elf file to a binary or hex file that can be loaded to flash, effectively striping out the debug
information leaving only the optimized code in ROM.

But if I re-build with options the same except omit the -g option, obviously I will have no symbols in the elf file making debugging impossible or at least more difficult. However, when I object copy this elf to a binary or hex file they are different somewhat than the binary or hex produced with options -g present. At least with 4.7.3 the main difference, as seen with objdump, is in the prologue to certain function calls with only a few bytes different in total code length on a fairly large embedded application (arm). So -g has some effect on the actual code produced it appears.

Is this difference expected? Should -g cause changes in the actual code generated and not just add debug symbols to the elf? Possibly it is related to the optimization level? I have not checked to see if the
results differ with higher or lower levels than -O1.

I have seen several opinions regarding this but no authoritative answer. The gcc manual also does not really answer this.

posted Jun 18, 2013 by anonymous

Share this question
Facebook Share Button Twitter Share Button LinkedIn Share Button

1 Answer

0 votes

If the only change in the command line options is whether you use -g, you should get exactly the same code. Any difference in code generation is a bug. Please try to file a bug report according to the guidelines at .

answer Jun 18, 2013 by anonymous
Similar Questions
0 votes

I'm curious about what is causing this reordering (prologue with the function parameters):

# gcc structs.c -o structs -m32 -O1 -fschedule-insns2

(gdb) disas main
Dump of assembler code for function main:
 0x0804868c : push %ebp
 0x0804868d : mov $0x3,%edx
 0x08048692 : mov %esp,%ebp
 0x08048694 : mov $0x2,%ecx
 0x08048699 : and $0xfffffff0,%esp
 0x0804869c : call 0x804845c 

The code:

__attribute__((fastcall)) void funcao(int i, int a) {
int main() {

 int i, a;
 i = 2;
 i = 3;

 funcao(i, a);

When I remove one of them (fastcall or schedule-insns2), the binary is generated in logic order:

(gdb) disas main
Dump of assembler code for function main:
 0x08048340 : push %ebp
 0x08048341 : mov %esp,%ebp
 0x08048343 : and $0xfffffff0,%esp
 0x08048346 : sub $0x10,%esp
 0x08048349 : movl $0x3,0x4(%esp)
 0x08048351 : movl $0x2,(%esp)
 0x08048358 : call 0x8048450 

... or

(gdb) disas main
Dump of assembler code for function main:
 0x0804868c : push %ebp
 0x0804868d : mov %esp,%ebp
 0x0804868f : and $0xfffffff0,%esp
 0x08048692 : mov $0x3,%edx
 0x08048697 : mov $0x2,%ecx
 0x0804869c : call 0x804845c 

Someone knows something about the combined use of the fastcall attribute and schedule-insns2 option? Is there an issue?

0 votes

I'm having trouble with link time optimization in my application. It is a large application that uses only basic C++ (no exceptions, no templates, no STL, no floating point, etc). Like many applications, the source files are compiled separately into object files. Some of those are combined into shared libraries. The shared libraries are then statically linked with the remaining object files to produce the final application, which is about 100MB big. We are using GCC 4.7.2 with a non-GOLD 2.23.1 binutils.

I simply added "-flto" to the GCC command to create object files:
g++ -Wall -pipe -O3 -flto -fno-strict-aliasing -mtune=generic --no-exceptions -fPIC -c

I then added "-flto" to the final link command but not the shared libraries:
g++ -o exec -Xlinker some1.o some2.o -static some1.a some2.a -Wl,--wrap,open -flto

I ran a benchmark of tests and the resulting execution time is now about 7% higher than it was without "-flto" added. Any suggestions for how to improve this result or why it may have gotten slower?

If it helps, when I add "-fuse-linker-plugin" I get this error:
g++: error: -fuse-linker-plugin is not supported in this configuration

0 votes

I've noticed the difference in gcc and llvm behaviour with the following code:

$ cat test.c

int main()
 for(int i = 0;; ({break;}))
 printf("Hello, worldn");

$ clang test.c -pedantic &; ({break;}))
1 warning generated.
Hello, world

$ gcc test.c -std=gnu11 -pedantic &; ({break;}))
test.c:5:21: warning: ISO C forbids braced-groups within expressions [-Wpedantic]
 for(int i = 0;; ({break;}))

So, llvm thinks that this is GNU extension (seems like it really is), but compiles it, and gcc does not, even if the standard is specified as gnu11. Is it a bug?

0 votes

How can we debug the segmentation fault in a program which has been compiled without "-g" option?

0 votes

is it possible to add a private extension to the core language (C/C++) by writing a gcc plugin?

The extension in mind is something like this


Later I want this be possible also inside statement headers, for example

for ([double d = 1.0; bool f = false;] size_t i = 0; i < vec.size(); ++i)

The scope of the so-defined variables shall be the same scope they are in, ie. in the for-loop case just the scope of the for-loop itself, much like the case with i.