* wrong code generated in gcc-4.1.1?
@ 2007-12-04 4:00 Hiroki Kaminaga
2007-12-04 5:45 ` [SOLVED] " Hiroki Kaminaga
2007-12-04 13:44 ` John Love-Jensen
0 siblings, 2 replies; 4+ messages in thread
From: Hiroki Kaminaga @ 2007-12-04 4:00 UTC (permalink / raw)
To: gcc-help; +Cc: kaminaga
Hi,
Below sample program produced wrong code in g++ version 4.1.1.
Is this a bug or am I violating C++ standard?
(not taking range propagation into account?)
$ cat test.c
#include <stdio.h>
typedef enum QUARTET {
PIANO = -1,
VIOLIN,
VIOLA,
CELLO
} Quartet;
enum {
FOURTY_TWO = 42
};
char *
getstring(Quartet q)
{
char *p;
int i = (int)q;
switch (i) {
case PIANO: p = "piano"; break;
case VIOLIN: p = "violin"; break;
case VIOLA: p = "viola"; break;
case CELLO: p = "cello"; break;
case FOURTY_TWO: p = "42"; break;
default: p = "unknown"; break;
}
return p;
}
int main()
{
Quartet q = VIOLIN;
printf("instrument: %s\n", getstring(q));
printf("instrument: %s\n", getstring((Quartet) FOURTY_TWO));
printf("instrument: %s\n", getstring((Quartet) 129));
return 0;
}
$ g++ --version
g++ (GCC) 4.1.1
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -O2 -o test test.c && ./test
instrument: violin
instrument: unknown
instrument: unknown
My expected result is:
instrument: violin
instrument: 42
instrument: unknown
I've seen the problem going away if:
- compiled with gcc (not g++)
- add -fno-tree-dominator-opts option
- set Quartet type `PIANO = ' to greater than or equal to zero
- compile with g++ version 3.4 serise
Any hint please?
Best Regards,
(Hiroki Kaminaga)
t
--
^ permalink raw reply [flat|nested] 4+ messages in thread
* [SOLVED] Re: wrong code generated in gcc-4.1.1?
2007-12-04 4:00 wrong code generated in gcc-4.1.1? Hiroki Kaminaga
@ 2007-12-04 5:45 ` Hiroki Kaminaga
2007-12-04 13:44 ` John Love-Jensen
1 sibling, 0 replies; 4+ messages in thread
From: Hiroki Kaminaga @ 2007-12-04 5:45 UTC (permalink / raw)
To: gcc-help; +Cc: kaminaga
Hi,
> Below sample program produced wrong code in g++ version 4.1.1.
> Is this a bug or am I violating C++ standard?
> (not taking range propagation into account?)
It was due to my lack of knowledge, "Programming Language C++ 3rd ed."
said assignment to enum which is out of range is undefined,
(or something like that in Japanese...), so it is not g++ generating
wrong code. Sorry for noice.
Best Regards,
(Hiroki Kaminaga)
t
--
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: wrong code generated in gcc-4.1.1?
2007-12-04 4:00 wrong code generated in gcc-4.1.1? Hiroki Kaminaga
2007-12-04 5:45 ` [SOLVED] " Hiroki Kaminaga
@ 2007-12-04 13:44 ` John Love-Jensen
2007-12-05 4:58 ` Hiroki Kaminaga
1 sibling, 1 reply; 4+ messages in thread
From: John Love-Jensen @ 2007-12-04 13:44 UTC (permalink / raw)
To: Hiroki Kaminaga, MSX to GCC
Hi Hiroki,
> Is this a bug or am I violating C++ standard?
The code violates the C++ standard.
The used range of Quartet is -1 ... 2, which can be expressed in 3 signed
bits (0b111 is -1, 0b010 is 2), a signed bit-range of -4 (0b100) to 3
(0b011).
42 and 129 do not fit in this range. Casting 42 and 129 into that range is
undefined.
The C++ compiler *KNOWS* that case FOURTY_TWO cannot be accessed, and is
dead code. Why? Because according to ISO 14882, Quartet *MUST* be between
-4 and 3 (3 signed bits). And it *KNOWS* that int i was set from a Quartet.
The optimization that is performing that behavior is -ftree-dominator-opts,
which is enabled by -O1 and higher.
If you compile the code as C (via gcc) instead of C++ (via g++), you'll
notice that the same -ftree-dominator-opts does not optimize away the
FOURTY_TWO. Why? Because in ISO 9899, an enum is held in a signed int or
an unsigned int.
Also some nits...
C++ should use the C++ header file, #include <cstdio>, and not the C header
file #include <stdio.h>.
And the return type should be char const*, and not char*.
And, in my opinion, C++ code should avoid using C-style casts and instead
should use C++ verbose casts.
HTH,
--Eljay
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: wrong code generated in gcc-4.1.1?
2007-12-04 13:44 ` John Love-Jensen
@ 2007-12-05 4:58 ` Hiroki Kaminaga
0 siblings, 0 replies; 4+ messages in thread
From: Hiroki Kaminaga @ 2007-12-05 4:58 UTC (permalink / raw)
To: eljay; +Cc: gcc-help, kaminaga
Hi,
> > Is this a bug or am I violating C++ standard?
>
> The code violates the C++ standard.
Thank you for reply and analysis!
> dead code. Why? Because according to ISO 14882, Quartet *MUST* be between
> -4 and 3 (3 signed bits). And it *KNOWS* that int i was set from a Quartet.
Thanks, I think you are refering to 5.2.9 paragraph 7, correct?
7 A value of integral type can be explicitly converted to an enumeration
type. The value is unchanged if the integral value is within the
range of the enumeration values (_dcl.enum_). Otherwise, the resulting
enumeration value is unspecified.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Best Regards,
(Hiroki Kaminaga)
t
--
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-12-05 4:58 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-04 4:00 wrong code generated in gcc-4.1.1? Hiroki Kaminaga
2007-12-04 5:45 ` [SOLVED] " Hiroki Kaminaga
2007-12-04 13:44 ` John Love-Jensen
2007-12-05 4:58 ` Hiroki Kaminaga
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).