VOOZH about

URL: https://en.wikibooks.org/wiki/Linux_Applications_Debugging_Techniques/The_compiler

⇱ Linux Applications Debugging Techniques/The compiler - Wikibooks, open books for an open world


Jump to content
From Wikibooks, open books for an open world

When requested to optimize ( and above), the compiler is granted a "total license" to modify it: treats undefined behavior (by the standard) as it cannot happen. Thus, the resulting code behaves differently in release-optimized mode than debug mode. Such differences in behavior cannot be found by static analyzers or code reviews.

Signed Integer Overflow

[edit | edit source]

1. This is C99 undefined behavior and the compiler assumes overflow cannot occur. Thus, any checks for overflow are discarded and the following is an infinite loop in optimized code:

inti,j=0;
for(i=1;i>0;i+=i){
++j;
}

2. The following:

(i*2000)/1000

is optimized into:

i*2
  • Use with to signal cases where code is optimized away.
  • Use

If lucky enough to use gcc 4.9 and later, you can use the ubsan sanitizer:

  • compile and link the program with option
  • use other available flags as needed.

Unsigned Wrap Around

[edit | edit source]

The compiler assumes unsigned integers do not wrap. Keep the unsigned variables in the range to avoid surprises.


"Dead Code" Removed

[edit | edit source]

The call could be removed because the compiler deems buf unused at that point in the code and after:

voiddo_something(void{
charbuf[123];
...usebuf...
/* Clear it. But removed by gcc: */
memset(buf,0,sizeof(buf));
}
  • Use directives to force the code in.
  • Use .


Pitfalls

[edit | edit source]

Code can be moved around:

volatileintflag=0;
charbuf[123];
voidinit_buf(){
for(size_ti=0;i<123;++i){
buf[i]=0;//Do something
}
flag=1;// Can move!
}

could be optimized into:

volatileintflag=0;
charbuf[123];
voidinit_buf(){
flag=1;// Moved!
for(size_ti=0;i<123;++i){
//Do something
}
}
  • Use compiler intrinsic barriers to prevent the flag moving.


Loops could be optimized into one read call only:

void*ptr=address;
while(*((volatileint*)ptr)&flag){}


Pointers

[edit | edit source]
  • Use
  • Use . Null pointer checks are deleted if placed after the first use of the pointer.


_STD_ANALYZABLE_

[edit | edit source]

References

[edit | edit source]