This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Optimisation puzzle


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]