On Wed, Jan 19, 2011 at 04:17:51PM +0100, Denys Vlasenko wrote:
> On Wed, Jan 19, 2011 at 3:45 PM, Johannes Stezenbach <[email protected]> wrote:
> >> But I have a deeper problem here. I do not see it as a good decision
> >> to butcher a readable piece of code into a obfuscated mess *only*
> >> to shut up gcc. gcc has to provide means to do it in some cleaner way.
> >
> > The gcc warning means: This is invalid code, it will break with
> > other compilers (including future gcc versions). The C99 standard
> > defines the aliasing rules precisely.
>
> I have no problem with warning per se. I have a problem with near
> impossibility to explain gcc that here I do want mii pointer
> to be treated as "can alias anything".
Well, I think the C99 aliasing rules are designed to allow better optimization.
BTW, if you don't believe the issue is real, try the following experiment
(here with gcc Debian 4.4.5-10 in x86):
struct foo {int i;};
struct bar {int i;};
int f(void)
{
struct foo foo = { 0 };
struct bar *bar = (struct bar *)&foo;
bar->i++;
return foo.i;
}
$ gcc -Wall -Os -c t.c
t.c: In function ‘f’:
t.c:8: warning: dereferencing pointer ‘bar’ does break strict-aliasing rules
t.c:7: note: initialized from here
$ objdump -dr t.o
t.o: file format elf32-i386
Disassembly of section .text:
00000000 <f>:
0: 55 push %ebp
1: 31 c0 xor %eax,%eax
3: 89 e5 mov %esp,%ebp
5: 83 ec 10 sub $0x10,%esp
8: c9 leave
9: c3 ret
As you can see the function returns 0 not 1.
However, adding some function calls:
struct foo {int i;};
struct bar {int i;};
void g(struct foo *);
int f(void)
{
struct foo foo = { 0 };
struct bar *bar = (struct bar *)&foo;
g(&foo);
bar->i++;
g(&foo);
return foo.i;
}
$ gcc -Wall -Os -c t.c
t.c: In function ‘f’:
t.c:12: warning: dereferencing pointer ‘bar’ does break strict-aliasing rules
t.c:9: note: initialized from here
$ objdump -dr t.o
t.o: file format elf32-i386
Disassembly of section .text:
0000000 <f>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 53 push %ebx
4: 83 ec 20 sub $0x20,%esp
7: 8d 5d f4 lea -0xc(%ebp),%ebx
a: 53 push %ebx
b: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
12: e8 fc ff ff ff call 13 <f+0x13>
13: R_386_PC32 g
17: 89 1c 24 mov %ebx,(%esp)
1a: ff 45 f4 incl -0xc(%ebp)
1d: e8 fc ff ff ff call 1e <f+0x1e>
1e: R_386_PC32 g
22: 8b 45 f4 mov -0xc(%ebp),%eax
25: 8b 5d fc mov -0x4(%ebp),%ebx
28: c9 leave
29: c3 ret
As you can see, foo.i on the stack is incremented before the
second function call. I'm not smart enough to read from
the C99 standard if this is OK (since function call is a sequence
point), or we were just lucky. So the particular example
from ifplugd.c might be OK despite the gcc warning, but
in general the "does break strict-aliasing rules" warning
means "it's broken".
If you think fixing the code is too ugly, the obvious
workaround is to use -fno-strict-aliasing. For the first
function it yields:
00000000 <f>:
0: 55 push %ebp
1: b8 01 00 00 00 mov $0x1,%eax
6: 89 e5 mov %esp,%ebp
8: 83 ec 10 sub $0x10,%esp
b: c9 leave
c: c3 ret
HTH
Johannes
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox