public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug preprocessor/27195]  New: hex and oct constants are converted to wrong type
@ 2006-04-18  8:15 mhx-perl at gmx dot net
  2006-04-18  8:17 ` [Bug preprocessor/27195] " mhx-perl at gmx dot net
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: mhx-perl at gmx dot net @ 2006-04-18  8:15 UTC (permalink / raw)
  To: gcc-bugs

The C99 standard states (6.4.4.1) that integer constants without a
suffix are converted to the first of the following types that can
represent their value:

  decimal constants: 1) int  2) long  3) long long
  hex/oct constants: 1) int  2) unsigned int  3) long  4) unsigned long
                     5) long long  6) unsigned long long

This works fine in the preprocessed code, but not within constant
preprocessor expressions, e.g.:

  #define XS 0x7fffffff

  #if XS > -1
  int xs = 1;
  #else
  int xs = 0;
  #endif

In this case, XS fits into an (int) and thus the comparison
is signed, resulting in xs == 1.

  #define XU 0x80000000

  #if XU > -1
  int xu = 1;
  #else
  int xu = 0;
  #endif

In this case, XU does not fit into an (int) and should rather
be an (unsigned), causing the -1 to be promoted and causing the
comparison to be unsigned, resulting in xu == 0.

However, it seems that the second case isn't handled correctly
by the gcc preprocessor, as it takes the xu == 1 path.

The attached code snippet shows that the gcc preprocessor doesn't
make a difference between dec/hex/oct constants, while the gcc
compiler does. The behaviour of the compiler looks correct to me.

Compile and run with:

  gcc -std=c99 -o const const.c
  ./const

I'd expect the output to be:

  1 - 0
  1 - 0
  1 - 0
  1 - 0
  1 - 1
  1 - 1

However, the output of my gcc-4.2 is

  $ gcc-4.2 -std=c99 -o const const.c && ./const
  1 - 1
  1 - 0
  1 - 1
  1 - 0
  1 - 1
  1 - 1

My gcc was compiled with:

  Using built-in specs.
  Target: i686-pc-linux-gnu
  Configured with: ../gcc-4.2-20060225/configure --program-suffix=-4.2
--prefix=/home/mhx/gcc/gcc-4.2-20060225 --enable-languages=c,c++ --disable-nls
  Thread model: posix
  gcc version 4.2.0 20060225 (experimental)

I've checked that the Intel C/C++ compiler (version 9.0)
produces the correct output:

  $ icc -std=c99 -o const const.c && ./const
  1 - 0
  1 - 0
  1 - 0
  1 - 0
  1 - 1
  1 - 1

Marcus


-- 
           Summary: hex and oct constants are converted to wrong type
           Product: gcc
           Version: 4.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: preprocessor
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: mhx-perl at gmx dot net
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27195


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug preprocessor/27195] hex and oct constants are converted to wrong type
  2006-04-18  8:15 [Bug preprocessor/27195] New: hex and oct constants are converted to wrong type mhx-perl at gmx dot net
@ 2006-04-18  8:17 ` mhx-perl at gmx dot net
  2006-04-18  8:21 ` rguenth at gcc dot gnu dot org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: mhx-perl at gmx dot net @ 2006-04-18  8:17 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from mhx-perl at gmx dot net  2006-04-18 08:17 -------
Created an attachment (id=11291)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=11291&action=view)
test code to reproduce the described behaviour


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27195


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug preprocessor/27195] hex and oct constants are converted to wrong type
  2006-04-18  8:15 [Bug preprocessor/27195] New: hex and oct constants are converted to wrong type mhx-perl at gmx dot net
  2006-04-18  8:17 ` [Bug preprocessor/27195] " mhx-perl at gmx dot net
@ 2006-04-18  8:21 ` rguenth at gcc dot gnu dot org
  2006-04-18 11:22 ` joseph at codesourcery dot com
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2006-04-18  8:21 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from rguenth at gcc dot gnu dot org  2006-04-18 08:21 -------
6.10.1/3

The resulting tokens
compose the controlling constant expression which is evaluated according to the
rules of
6.6, except that all signed integer types and all unsigned integer types act as
if they have
the same representation as, respectively, the types intmax_t and uintmax_t
defined
in the header <stdint.h>.


-- 

rguenth at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27195


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug preprocessor/27195] hex and oct constants are converted to wrong type
  2006-04-18  8:15 [Bug preprocessor/27195] New: hex and oct constants are converted to wrong type mhx-perl at gmx dot net
  2006-04-18  8:17 ` [Bug preprocessor/27195] " mhx-perl at gmx dot net
  2006-04-18  8:21 ` rguenth at gcc dot gnu dot org
@ 2006-04-18 11:22 ` joseph at codesourcery dot com
  2006-04-18 13:26 ` mhx-perl at gmx dot net
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: joseph at codesourcery dot com @ 2006-04-18 11:22 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from joseph at codesourcery dot com  2006-04-18 11:22 -------
Subject: Re:  hex and oct constants are converted to
 wrong type

On Tue, 18 Apr 2006, rguenth at gcc dot gnu dot org wrote:

> 6.10.1/3
> 
> The resulting tokens
> compose the controlling constant expression which is evaluated according to the
> rules of
> 6.6, except that all signed integer types and all unsigned integer types act as
> if they have
> the same representation as, respectively, the types intmax_t and uintmax_t
> defined
> in the header <stdint.h>.

I recommend quoting the current standard as amended by TC2, which makes 
this specific case even clearer in response to DR#265:

  The resulting tokens compose the controlling constant expression which 
  is evaluated according to the rules of 6.6. For the purposes of this 
  token conversion and evaluation, all signed integer types and all 
  unsigned integer types act as if they have the same representation as, 
  respectively, the types intmax_t and uintmax_t defined in the header 
  <stdint.h>.142)

  142) Thus, on an implementation where INT_MAX is 0x7FFF and UINT_MAX is 
  0xFFFF, the constant 0x8000 is signed and positive within a #if 
  expression even though it would be unsigned in translation phase 7.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27195


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug preprocessor/27195] hex and oct constants are converted to wrong type
  2006-04-18  8:15 [Bug preprocessor/27195] New: hex and oct constants are converted to wrong type mhx-perl at gmx dot net
                   ` (2 preceding siblings ...)
  2006-04-18 11:22 ` joseph at codesourcery dot com
@ 2006-04-18 13:26 ` mhx-perl at gmx dot net
  2006-10-26  6:45 ` lukew at radterm dot com dot au
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: mhx-perl at gmx dot net @ 2006-04-18 13:26 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from mhx-perl at gmx dot net  2006-04-18 13:26 -------
Subject: Re:  hex and oct constants are converted to
 wrong type

On 2006-04-18, at 11:22:00 -0000, joseph at codesourcery dot com wrote:

>   142) Thus, on an implementation where INT_MAX is 0x7FFF and UINT_MAX is 
>   0xFFFF, the constant 0x8000 is signed and positive within a #if 
>   expression even though it would be unsigned in translation phase 7.

Thanks for that quote!

So it's the Intel compiler that is actually wrong (even
though its behaviour seemed more consistent to me in the
first place), as it reuses the system's stdint.h, which
defines intmax_t and uintmax_t as 64-bit types.

Thanks again and sorry for the bogus report,
Marcus


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27195


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug preprocessor/27195] hex and oct constants are converted to wrong type
  2006-04-18  8:15 [Bug preprocessor/27195] New: hex and oct constants are converted to wrong type mhx-perl at gmx dot net
                   ` (3 preceding siblings ...)
  2006-04-18 13:26 ` mhx-perl at gmx dot net
@ 2006-10-26  6:45 ` lukew at radterm dot com dot au
  2006-10-26 12:42 ` neil at daikokuya dot co dot uk
  2006-10-27  3:51 ` lukew at radterm dot com dot au
  6 siblings, 0 replies; 8+ messages in thread
From: lukew at radterm dot com dot au @ 2006-10-26  6:45 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from lukew at radterm dot com dot au  2006-10-26 06:45 -------
(In reply to comment #3)
> Subject: Re:  hex and oct constants are converted to
>  wrong type

>   The resulting tokens compose the controlling constant expression which 
>   is evaluated according to the rules of 6.6. For the purposes of this 
>   token conversion and evaluation, all signed integer types and all 
>   unsigned integer types act as if they have the same representation as, 
>   respectively, the types intmax_t and uintmax_t defined in the header 
>   <stdint.h>.142)
> 
>   142) Thus, on an implementation where INT_MAX is 0x7FFF and UINT_MAX is 
>   0xFFFF, the constant 0x8000 is signed and positive within a #if 
>   expression even though it would be unsigned in translation phase 7.
> 

I don't get it.

How can 0x8000 be signed AND positive when INT_MAX is a 16 bit integer?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27195


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug preprocessor/27195] hex and oct constants are converted to wrong type
  2006-04-18  8:15 [Bug preprocessor/27195] New: hex and oct constants are converted to wrong type mhx-perl at gmx dot net
                   ` (4 preceding siblings ...)
  2006-10-26  6:45 ` lukew at radterm dot com dot au
@ 2006-10-26 12:42 ` neil at daikokuya dot co dot uk
  2006-10-27  3:51 ` lukew at radterm dot com dot au
  6 siblings, 0 replies; 8+ messages in thread
From: neil at daikokuya dot co dot uk @ 2006-10-26 12:42 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from neil at daikokuya dot co dot uk  2006-10-26 12:42 -------
Subject: Re:  hex and oct constants are converted to wrong type

lukew at radterm dot com dot au wrote:-

> >   The resulting tokens compose the controlling constant expression which 
> >   is evaluated according to the rules of 6.6. For the purposes of this 
> >   token conversion and evaluation, all signed integer types and all 
> >   unsigned integer types act as if they have the same representation as, 
> >   respectively, the types intmax_t and uintmax_t defined in the header 
> >   <stdint.h>.142)
> > 
> >   142) Thus, on an implementation where INT_MAX is 0x7FFF and UINT_MAX is 
> >   0xFFFF, the constant 0x8000 is signed and positive within a #if 
> >   expression even though it would be unsigned in translation phase 7.
> > 
> 
> I don't get it.
> 
> How can 0x8000 be signed AND positive when INT_MAX is a 16 bit integer?

Ask yourself what its type is.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27195


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug preprocessor/27195] hex and oct constants are converted to wrong type
  2006-04-18  8:15 [Bug preprocessor/27195] New: hex and oct constants are converted to wrong type mhx-perl at gmx dot net
                   ` (5 preceding siblings ...)
  2006-10-26 12:42 ` neil at daikokuya dot co dot uk
@ 2006-10-27  3:51 ` lukew at radterm dot com dot au
  6 siblings, 0 replies; 8+ messages in thread
From: lukew at radterm dot com dot au @ 2006-10-27  3:51 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from lukew at radterm dot com dot au  2006-10-27 03:51 -------
(In reply to comment #6)
> Subject: Re:  hex and oct constants are converted to wrong type
> 
> lukew at radterm dot com dot au wrote:-
> 
> > >   The resulting tokens compose the controlling constant expression which 
> > >   is evaluated according to the rules of 6.6. For the purposes of this 
> > >   token conversion and evaluation, all signed integer types and all 
> > >   unsigned integer types act as if they have the same representation as, 
> > >   respectively, the types intmax_t and uintmax_t defined in the header 
> > >   <stdint.h>.142)
> > > 
> > >   142) Thus, on an implementation where INT_MAX is 0x7FFF and UINT_MAX is 
> > >   0xFFFF, the constant 0x8000 is signed and positive within a #if 
> > >   expression even though it would be unsigned in translation phase 7.
> > > 
> > 
> > I don't get it.
> > 
> > How can 0x8000 be signed AND positive when INT_MAX is a 16 bit integer?
> 
> Ask yourself what its type is.
> 

intmax_t and INTMAX_MAX is 0x7FFFFFFFFFFFFFFF.

0x8000000000000000 is unsigned

where as (INTMAX_MAX + 1) is signed and negative.

Which is fine.

Thanks Neil.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27195


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-10-27  3:51 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-18  8:15 [Bug preprocessor/27195] New: hex and oct constants are converted to wrong type mhx-perl at gmx dot net
2006-04-18  8:17 ` [Bug preprocessor/27195] " mhx-perl at gmx dot net
2006-04-18  8:21 ` rguenth at gcc dot gnu dot org
2006-04-18 11:22 ` joseph at codesourcery dot com
2006-04-18 13:26 ` mhx-perl at gmx dot net
2006-10-26  6:45 ` lukew at radterm dot com dot au
2006-10-26 12:42 ` neil at daikokuya dot co dot uk
2006-10-27  3:51 ` lukew at radterm dot com dot au

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).