Optimisation puzzle

Ian Lance Taylor iant@google.com
Fri Mar 16 21:35:00 GMT 2007


Erik <sigra@home.se> writes:

>  From man:puts I see that it is declared "int puts(const char
> *)". This means that puts does not promise to leave its argument
> unchanged. Therefore the caller must push the argument anew before
> each call. If it had been declared "int puts(const char * const)"
> instead, the push should be moved outside the loop. Unfortunately this
> does not seem to work. I tried with the following program:
> void q(const unsigned int);
> void f() {for (unsigned int x = 0; x != 10; x++) q(77);}
> 
> and built it with "gcc -std=c99 -Os -Wall -Wextra -Werror -S":
> .L2:
>         subl    $12, %esp
>         incl    %ebx
>         pushl   $77
>         call    q
>         addl    $16, %esp
>         cmpl    $10, %ebx
>         jne     .L2
> 
> As you can see, "pushl   $77" is still inside the loop even though q
> promises to not change its argument. This must be a bug.

This is not a bug.  const on an automatic variable in C is more
advisory than anything else.  You are not permitted to change a const
object, but you can cast its address to a non-const pointer.  The only
time const really means something is when it is applied to a global or
static variable.  In that case the compiler is permitted to put the
variable in read-only storage.

That is, this is legal C:

int
q (const unsigned int i)
{
  int *p = (int *) &i;
  *p = 1;
  return i;
}

Ian



More information about the Gcc-help mailing list