Invalid Compiler Warning? 
Author Message
 Invalid Compiler Warning?

Hi,

I have the following test program:
#include <stdio.h>

typedef unsigned char   UINT8;

int main(void)
{
    UINT8   value = ~0;
    printf("Value: 0x%02X\n", value);
    return 0;

Quote:
}

The ARM Compiler (Arm Project Manager) gives me the warning:
Warning:      "uint8.c"; line 7 implicit cast (to 'unsigned char') overflow

The GNU Gcc compiler, 2.95.3, does not issue any warnings.
I used the command line:  gcc -Wall -o uint8 uint8.c

The _Harbison_and_Steele_ book does not mention anything about warnings
for bitwise negation (section 7.5.5).

Which compiler is correct?

-- Thomas Matthews



Sun, 03 Apr 2005 23:21:06 GMT  
 Invalid Compiler Warning?

Quote:

> Hi,

> I have the following test program:
> #include <stdio.h>

> typedef unsigned char   UINT8;

> int main(void)
> {
>     UINT8   value = ~0;

If int is e.g. 16bit wide, ~0 would produce 0xFFFF (2's complement).
And this overflows 8bit unsigned char.

Jirka



Sun, 03 Apr 2005 23:29:02 GMT  
 Invalid Compiler Warning?


Quote:
> Hi,

> I have the following test program:
> #include <stdio.h>

> typedef unsigned char   UINT8;

> int main(void)
> {
>     UINT8   value = ~0;
>     printf("Value: 0x%02X\n", value);
>     return 0;
> }

> The ARM Compiler (Arm Project Manager) gives me the warning:
> Warning:      "uint8.c"; line 7 implicit cast (to 'unsigned char')
overflow

> The GNU Gcc compiler, 2.95.3, does not issue any warnings.
> I used the command line:  gcc -Wall -o uint8 uint8.c

> The _Harbison_and_Steele_ book does not mention anything about warnings
> for bitwise negation (section 7.5.5).

> Which compiler is correct?

They both are.  According to the Standard, there is no mandatory error
message there.  However, any compiler is free to produce any diagnostics
(e.g. warning messagess) it feels like.

BTW: the warning isn't about the bitwise negation; it's for initializing a
object of type UINT8 with a value that does not fit into that type.  The
expression ~0 is (at a minimum) 65535, and values of that size do not fit
within the ARM compiler's unsigned char type.  This is not an error; for
unsigned types, there is a defined method of doing the conversion.  However,
the ARM compiler tried to be helpful in telling you that it was doing so.

To quiet the compiler, you could try:

  UINT8 value = (UINT8)~0;

--
poncho



Sun, 03 Apr 2005 23:40:13 GMT  
 Invalid Compiler Warning?

Quote:

> [...]
> typedef unsigned char   UINT8;

> int main(void)
> {
>     UINT8   value = ~0;
> [...]

> The ARM Compiler (Arm Project Manager) gives me the warning:
> Warning:      "uint8.c"; line 7 implicit cast (to 'unsigned char') overflow

> The GNU Gcc compiler, 2.95.3, does not issue any warnings.
> I used the command line:  gcc -Wall -o uint8 uint8.c

> The _Harbison_and_Steele_ book does not mention anything about warnings
> for bitwise negation (section 7.5.5).

> Which compiler is correct?

    Both.  The compiler is permitted to issue whatever warnings
its implementors thought might be helpful.  It can complain or
be silent about unreachable statements, about suspicious type
conversions, or about spelling errors in your commemts.  Some
compilers, for example, will issue a warning message for

        if (x = 0)
            printf ("Warning: x is zero!\n");

even though it's perfectly valid C code -- and most programmers
consider this a Good Thing because it draws their attention to
the fact that this perfectly valid code probably doesn't do
what was intended.  Count your blessings.

--



Mon, 04 Apr 2005 02:57:06 GMT  
 Invalid Compiler Warning?


Quote:
> The ARM Compiler (Arm Project Manager) gives me the warning:
> Warning:      "uint8.c"; line 7 implicit cast (to 'unsigned char') overflow

> The GNU Gcc compiler, 2.95.3, does not issue any warnings.
> I used the command line:  gcc -Wall -o uint8 uint8.c

Other people have answered your particular question, but I'll take the
opportunity to point out that the Norcroft (ARM) compiler is a lot stricter
than gcc, and generally more standard-conformant, so you will often be
getting warnings or errors you may not expect if you're used to gcc. It's
generally right though (or for warnings like this, just trying to be
helpful).

Tragically, ARM have gradually been reducing the strictness of the compiler
in response to customer demand :(

--
Kevin Bracey
http://www.bracey-griffith.freeserve.co.uk/



Mon, 04 Apr 2005 03:33:57 GMT  
 Invalid Compiler Warning?

Quote:


> > Hi,

> > I have the following test program:
> > #include <stdio.h>

> > typedef unsigned char   UINT8;

> > int main(void)
> > {
> >     UINT8   value = ~0;

> If int is e.g. 16bit wide, ~0 would produce 0xFFFF (2's complement).
> And this overflows 8bit unsigned char.

> Jirka

But 8-bit wide, ~0 should produce 0xFF (one's complement).
Why does it overflow?
I don't see why a 1's complement should oveflow.

-- Thomas Matthews



Mon, 04 Apr 2005 05:46:44 GMT  
 Invalid Compiler Warning?

Quote:



> > Hi,

> > I have the following test program:
> > #include <stdio.h>

> > typedef unsigned char   UINT8;

> > int main(void)
> > {
> >     UINT8   value = ~0;
> >     printf("Value: 0x%02X\n", value);
> >     return 0;
> > }

> > The ARM Compiler (Arm Project Manager) gives me the warning:
> > Warning:      "uint8.c"; line 7 implicit cast (to 'unsigned char')
> overflow

> > The GNU Gcc compiler, 2.95.3, does not issue any warnings.
> > I used the command line:  gcc -Wall -o uint8 uint8.c

> > The _Harbison_and_Steele_ book does not mention anything about warnings
> > for bitwise negation (section 7.5.5).

> > Which compiler is correct?
> They both are.  According to the Standard, there is no mandatory error
> message there.  However, any compiler is free to produce any diagnostics
> (e.g. warning messagess) it feels like.

> BTW: the warning isn't about the bitwise negation; it's for initializing a
> object of type UINT8 with a value that does not fit into that type.  The
> expression ~0 is (at a minimum) 65535, and values of that size do not fit
> within the ARM compiler's unsigned char type.  This is not an error; for
> unsigned types, there is a defined method of doing the conversion.  However,
> the ARM compiler tried to be helpful in telling you that it was doing so.

> To quiet the compiler, you could try:

>   UINT8 value = (UINT8)~0;

> --
> poncho

Why is ~0 a 16 bit quantity?
The compiler also yelled at:
    UINT8 = ~'\0';

-- Thomas



Mon, 04 Apr 2005 05:48:08 GMT  
 Invalid Compiler Warning?

Quote:



> > The ARM Compiler (Arm Project Manager) gives me the warning:
> > Warning:      "uint8.c"; line 7 implicit cast (to 'unsigned char') overflow

> > The GNU Gcc compiler, 2.95.3, does not issue any warnings.
> > I used the command line:  gcc -Wall -o uint8 uint8.c

> Other people have answered your particular question, but I'll take the
> opportunity to point out that the Norcroft (ARM) compiler is a lot stricter
> than gcc, and generally more standard-conformant, so you will often be
> getting warnings or errors you may not expect if you're used to gcc. It's
> generally right though (or for warnings like this, just trying to be
> helpful).

> Tragically, ARM have gradually been reducing the strictness of the compiler
> in response to customer demand :(

> --
> Kevin Bracey
> http://www.bracey-griffith.freeserve.co.uk/

I'm just confused how an 8-bit quantity could overflow an an 8-bit variable.

If I assign the constant 36 to an unsigned char variable, there is no complaint.
One is led to believe that 36 is an 8-bit quantity.

So why is ~0 considered to be a 16-bit quantity?
Why not 32 or 64?

My understanding was that the expression '~0' would be calculated in terms
of unsigned character since that was the type on the left-hand side.

-- Thomas Matthews



Mon, 04 Apr 2005 05:51:53 GMT  
 Invalid Compiler Warning?

Quote:

> If I assign the constant 36 to an unsigned char variable, there
> is no complaint.  One is led to believe that 36 is an 8-bit
> quantity.

It isn't.  It is at least 16 bits in size, because small integer
constants in C have type int and int is at least 16 bits in size.

Quote:
> So why is ~0 considered to be a 16-bit quantity?
> Why not 32 or 64?

It could be 32 or 64 if that's the size of your int.

Quote:
> My understanding was that the expression '~0' would be calculated in terms
> of unsigned character since that was the type on the left-hand side.

Your understanding is incorrect.  The type on the left-hand side
of an assignment does not affect how arithmetic is performed on
the right-hand side.
--
"Am I missing something?"
--Dan Pop


Mon, 04 Apr 2005 05:54:03 GMT  
 Invalid Compiler Warning?

Quote:

> Why is ~0 a 16 bit quantity?

Because 0 has type int and you're (presumably) using a system
with a 16-bit int.

Small integer constants in C have type int.

Quote:
> The compiler also yelled at:
>     UINT8 = ~'\0';

0 and '\0' have the same type and value.  Both have type int and
value zero.  And you can't assign to a type, only to a variable.
--
"The expression isn't unclear *at all* and only an expert could actually
 have doubts about it"
--Dan Pop


Mon, 04 Apr 2005 05:52:26 GMT  
 Invalid Compiler Warning?


Quote:
> I'm just confused how an 8-bit quantity could overflow an an 8-bit
> variable.

That's not unreasonable in this case.

Quote:
> If I assign the constant 36 to an unsigned char variable, there is no
> complaint. One is led to believe that 36 is an 8-bit quantity.

That's because 36 fits into an unsigned char. It's not really a question of
being "8-bit" or "16-bit". It's just a question of whether the value fits.

Quote:
> So why is ~0 considered to be a 16-bit quantity?

32-bit, actually, in the case of the ARM compiler. Here's how it goes:

  1)  0 is an "int".
  2)  An "int" is 32 bits on this compiler.
  3)  Thus ~0 = 0xFFFFFFFF.
  4)  0xFFFFFFFF does not fit into an unsigned char.
  5)  Thus the compiler gives you a 'helpful' warning (although the behaviour
      is well defined, and you must end up with 0xFF in 'a'). [Pedants:
      char being 8-bit here].

What you'd like is a way of doing an 8-bit "~" operation. C won't let you do
this, unfortunately, as all operands are promoted to at least "int" before
operations take place.

One way to shut the compiler up would be to define a simple macro:

      #define INVERTCHAR(a) ((a) ^ (unsigned char) -1)

      unsigned char a = INVERTCHAR(0);

The other way is just to explicitly cast, which makes the compiler think you
know what you're doing:

      unsigned char a = (unsigned char) ~0;

Alternatively, there may be a compiler option to disable that particular
warning.

Quote:
> My understanding was that the expression '~0' would be calculated in terms
> of unsigned character since that was the type on the left-hand side.

Afraid not, expressions always evaluate the same way, regardless of where
they're going to end up. Same problem as the frequently-asked
"float f = 1 / 2;" not working.

--
Kevin Bracey
http://www.bracey-griffith.freeserve.co.uk/



Mon, 04 Apr 2005 06:50:22 GMT  
 Invalid Compiler Warning?

Quote:



> > The ARM Compiler (Arm Project Manager) gives me the warning:
> > Warning:      "uint8.c"; line 7 implicit cast (to 'unsigned char') overflow

> > The GNU Gcc compiler, 2.95.3, does not issue any warnings.
> > I used the command line:  gcc -Wall -o uint8 uint8.c

> Other people have answered your particular question, but I'll take the
> opportunity to point out that the Norcroft (ARM) compiler is a lot stricter
> than gcc, and generally more standard-conformant, so you will often be
> getting warnings or errors you may not expect if you're used to gcc. It's
> generally right though (or for warnings like this, just trying to be
> helpful).

   gcc -W -Wall -ansi -pedantic -O2

will find more problem areas. (without the -On it won't find
unused variables).  You can also use splint.

--

   Available for consulting/temporary embedded and systems.
   <http://cbfalconer.home.att.net>  USE worldnet address!



Mon, 04 Apr 2005 08:28:46 GMT  
 Invalid Compiler Warning?
On Wed, 16 Oct 2002 23:50:22 +0100, Kevin Bracey

Quote:


> > I'm just confused how an 8-bit quantity could overflow an an 8-bit
> > variable.

> That's not unreasonable in this case.

> > If I assign the constant 36 to an unsigned char variable, there is no
> > complaint. One is led to believe that 36 is an 8-bit quantity.

> That's because 36 fits into an unsigned char. It's not really a question of
> being "8-bit" or "16-bit". It's just a question of whether the value fits.

> > So why is ~0 considered to be a 16-bit quantity?

> 32-bit, actually, in the case of the ARM compiler. Here's how it goes:

>   1)  0 is an "int".
>   2)  An "int" is 32 bits on this compiler.
>   3)  Thus ~0 = 0xFFFFFFFF.
>   4)  0xFFFFFFFF does not fit into an unsigned char.
>   5)  Thus the compiler gives you a 'helpful' warning (although the behaviour
>       is well defined, and you must end up with 0xFF in 'a'). [Pedants:
>       char being 8-bit here].

> What you'd like is a way of doing an 8-bit "~" operation. C won't let you do
> this, unfortunately, as all operands are promoted to at least "int" before
> operations take place.

In fact the ARM core can't do pure 8 bit operations at all.  It is a
much "purer" C machine than something like the x86 with its multiple
register sizes.

When an ARM processor accesses a (signed or unsigned) char (8 bits on
ARM) or short (16 bits on ARM), the value is always automatically sign
or zero extended to fill a 32 bit register.  All integer arithmetic
and logical operations are always performed on the full 32 bit
register.  There are no 8 or 16 bit instructions.

- Show quoted text -

Quote:

> One way to shut the compiler up would be to define a simple macro:

>       #define INVERTCHAR(a) ((a) ^ (unsigned char) -1)

>       unsigned char a = INVERTCHAR(0);

> The other way is just to explicitly cast, which makes the compiler think you
> know what you're doing:

>       unsigned char a = (unsigned char) ~0;

> Alternatively, there may be a compiler option to disable that particular
> warning.

> > My understanding was that the expression '~0' would be calculated in terms
> > of unsigned character since that was the type on the left-hand side.

> Afraid not, expressions always evaluate the same way, regardless of where
> they're going to end up. Same problem as the frequently-asked
> "float f = 1 / 2;" not working.

Beyond that, there is no expression involving an arithmetic or logical
operation in C that is ever carried out on integer types smaller than
signed or unsigned int.  char and short types are always promoted to
signed or unsigned int (or to a larger type) in these types of
expressions.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq



Mon, 04 Apr 2005 14:06:56 GMT  
 Invalid Compiler Warning?


Quote:
> In fact the ARM core can't do pure 8 bit operations at all.  It is a
> much "purer" C machine than something like the x86 with its multiple
> register sizes.

> When an ARM processor accesses a (signed or unsigned) char (8 bits on
> ARM) or short (16 bits on ARM), the value is always automatically sign
> or zero extended to fill a 32 bit register.  All integer arithmetic
> and logical operations are always performed on the full 32 bit
> register.  There are no 8 or 16 bit instructions.

They're beginning to appear. The new-fangled 16-bit memory access
instructions were the start of the downhill slide, but newer revisions of the
architecture are growing 16x16->32 multiplies, parallel 16+16->16 additions,
etc etc. Blurgh. Nothing that a compiler can easily take advantage of
terribly easily.

It's not exactly the Acorn/Advanced "RISC" Machine anymore - architecture 6
adds four times as many instructions as the first ARM had in total :)

But yes, it's an interesting point that the automatic promotion to int was
almost designed for the ARM; it would be very painful having to keep
truncating results to 8 or 16 bits in the middle of expressions. I've been
working on the ARM so long, I'd forgotten that other weird processors used to
have variable width registers.

--
Kevin Bracey
http://www.bracey-griffith.freeserve.co.uk/



Mon, 04 Apr 2005 16:44:54 GMT  
 Invalid Compiler Warning?

Quote:


>> The ARM Compiler (Arm Project Manager) gives me the warning:
>> Warning:      "uint8.c"; line 7 implicit cast (to 'unsigned char') overflow

>> The GNU Gcc compiler, 2.95.3, does not issue any warnings.
>> I used the command line:  gcc -Wall -o uint8 uint8.c

>Other people have answered your particular question, but I'll take the
>opportunity to point out that the Norcroft (ARM) compiler is a lot stricter
>than gcc,

This is a pointless remark: compilers either are conforming or not.

Quote:
>and generally more standard-conformant,

Another pointless remark, for the same reason.

Quote:
>so you will often be
>getting warnings or errors you may not expect if you're used to gcc.

When used in conforming mode, gcc produces all the diagnostics required
by the standard, AFAICT.  So, if you get an error diagnostic from another
compiler, while gcc -ansi -pedantic silently accepts the code, it is more
likely that the other compiler is broken (by error diagnostic I mean a
diagnostic that prevents the successful translation and execution of the
program).

Of course, "warnings" are a completely different issue, each implementor
has his own ideas about what is a helpful warning.

Quote:
>It's
>generally right though (or for warnings like this, just trying to be
>helpful).

But that's the real problem: by warning about this perfectly correct
program construct, the compiler effectively forces the programmer to
introduce an *unneeded* cast (or to live with the annoying diagnostic).  
Many people consider unneeded casts to be harmful.  Therefore, such
warnings are more annoying than helpful.

Dan
--
Dan Pop
DESY Zeuthen, RZ group



Mon, 04 Apr 2005 19:27:24 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. C4201 and C4214 warnings at Compiler Warning Level 4

2. Compiler error: invalid type for __gc array element

3. Invalid Page Fault in Release mode with ML compiler option

4. Invalid Page Fault in Release mode with ML compiler option

5. .Net 2003 compiler warning

6. Compiler warning C4530 in VC6.0 migrated project

7. compiler warning

8. Strange MC++ compiler warning.

9. Compiler warnings

10. constant assert without compiler warning

11. Missing compiler warning - suggestion

12. compiler warning of internal virtual member

 

 
Powered by phpBB® Forum Software