conversion #3

  • Follow


Hello,

typedef struct {
        UCHAR Num;
        UCHAR Mask;
        UCHAR Val;
} IRVType, *PIRVType;
....
bool SetIRVBit(PIRVType pIRV, UCHAR Num, UCHAR Mask, UCHAR Val)
{
   while (pIRV->Num || pIRV->Mask || pIRV->Val)
   {
      if (pIRV->Num!=Num)
      {
         pIRV++;
         continue;
      }

      pIRV->Mask|=Mask;
      pIRV->Val&=~Mask;
      pIRV->Val|=Val;
      return TRUE;
   }
   return FALSE;
}

Compiling it with borland builder results with warning on "pIRV->Val&=~Mask" 
line: "conversion may loose significant digits". Both operands are 
(pIRV->Val and Mask) of the same type (UCHAR, which is 'unsigned char'). 
What's wrong with this snippet?

Thanks.

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply mrv (331) 11/17/2007 12:36:46 AM

Roman Mashak said:

<snip>
 
> Compiling it with borland builder results with warning on
> "pIRV->Val&=~Mask" line: "conversion may loose significant digits". Both
> operands are (pIRV->Val and Mask) of the same type (UCHAR, which is
> 'unsigned char'). What's wrong with this snippet?

Nothing. The "significant digits" that you might lose are insignificant, 
since they are a side-effect of promotion with which you need not concern 
yourself for the purposes of this line of code.

Let's assume 8-bit bytes, 2-byte ints (because it's less to type).

We'll assume pIRV->Val has the value 00111101, and Mask has the value 
10101010.

If you thought ~Mask was 01010101, you'd be forgivably wrong. It's actually 
1111111101010101 (on the system we're assuming). When you & this with 
00111101 (or rather, 0000000000111101) you get 0000000000010101, and you 
then store this in an unsigned char, getting 00010101, which is precisely 
what you want.

If your system has bigger bytes, bigger ints, or both, then you just get 
more leading 0s to ignore. No big deal.

-- 
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
0
Reply rjh (10789) 11/16/2007 8:12:11 AM


Roman Mashak said:

<snip>

>  RH> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
>  RH> actually
>  RH> 1111111101010101 (on the system we're assuming). When you & this
>  with
> 
> Does it have something to do with alignment? Why is byte converted to
> int?

On (possibly spurious) efficiency grounds.

-- 
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
0
Reply rjh (10789) 11/16/2007 9:27:51 AM

Roman Mashak said:

> Hello, Richard!
> You wrote  on Fri, 16 Nov 2007 09:27:51 +0000:
> 
>  RH>>> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
>  RH>>> actually
>  RH>>> 1111111101010101 (on the system we're assuming). When you & this
>  ??>>  with
>  ??>>
>  ??>> Does it have something to do with alignment? Why is byte converted
>  to ??>> int?
> 
>  RH> On (possibly spurious) efficiency grounds.
> Are these grounds declared by ANSI standard,

Not in so many words, no, but the Standard does say that "A ``plain'' int 
object has the natural size suggested by the architecture of the execution 
environment". The values of objects of smaller size very often (always?) 
get promoted to this "natural size" during calculations.

> is this conversion required
> to be done by every implementation?

Yes. Look up "integer promotion" and "the usual arithmetic conversions".

-- 
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
0
Reply rjh (10789) 11/16/2007 9:52:02 AM

Richard Heathfield wrote:
> Roman Mashak said:
> 
> <snip>
> 
>>  RH> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
>>  RH> actually
>>  RH> 1111111101010101 (on the system we're assuming). When you & this
>>  with
>>
>> Does it have something to do with alignment? Why is byte converted to
>> int?
> 
> On (possibly spurious) efficiency grounds.

     ... for very small values of "possibly."  Lots of machines
that implement C lack the ability to perform arithmetic on
"narrow" operands like `short x' or `char y' or `int z : 3'.
Usually, a machine that can't perform three-bit arithmetic
will instead load the narrow quantity into a wider "register"
or something of the kind, use its native wide arithmetic to
operate on the widened operand, and then store part of the
wide result into a narrow destination.  C's "promotions" are
a recognition of this common implementation practice.

     (It's been almost forty years since I last encountered
a machine that could do "native" arithmetic on a three-bit
integer.)

-- 
Eric Sosman
esosman@ieee-dot-org.invalid
0
Reply esosman2 (2945) 11/16/2007 1:52:42 PM

Eric Sosman said:
> Richard Heathfield wrote:
>> Roman Mashak said:
>> 
>>> Why is byte converted to int?
>> 
>> On (possibly spurious) efficiency grounds.
> 
>      ... for very small values of "possibly."

32-bit char, anyone? Lots of those around in the embedded world. Promotion 
to int on efficiency grounds is 100% pointless on CSILP32 systems.

-- 
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
0
Reply rjh (10789) 11/16/2007 3:40:36 PM

Roman Mashak wrote:
> 
> typedef struct {
>         UCHAR Num;
>         UCHAR Mask;
>         UCHAR Val;
> } IRVType, *PIRVType;
> ...
> bool SetIRVBit(PIRVType pIRV, UCHAR Num, UCHAR Mask, UCHAR Val)
> {
>    while (pIRV->Num || pIRV->Mask || pIRV->Val) {
>       if (pIRV->Num!=Num) {
>          pIRV++;
>          continue;
>       }
>       pIRV->Mask|=Mask;
>       pIRV->Val&=~Mask;
>       pIRV->Val|=Val;
>       return TRUE;
>    }
>    return FALSE;
> }
> 
> Compiling it with borland builder results with warning on "pIRV->Val&=~Mask"
> line: "conversion may loose significant digits". Both operands are
> (pIRV->Val and Mask) of the same type (UCHAR, which is 'unsigned char').
> What's wrong with this snippet?

No they're not.  One is of the type ~Mask, which is an int.  

In addition, I believe your cavalier action of incrementing the
pointer pIRV should be flagged as an error.  Pointers are not
integers.

Thirdly, you are using the type 'bool'.  This implies the use of
C99, and #include <stdbool.h>.  This also defines the standard
values true and false (lower case).

-- 
 Chuck F (cbfalconer at maineline dot net)
   <http://cbfalconer.home.att.net>
   Try the download section.



-- 
Posted via a free Usenet account from http://www.teranews.com

0
Reply cbfalconer (19183) 11/16/2007 5:08:47 PM

Hello, Richard!
You wrote  on Fri, 16 Nov 2007 08:12:11 +0000:

[skip]
 RH> Let's assume 8-bit bytes, 2-byte ints (because it's less to type).

 RH> We'll assume pIRV->Val has the value 00111101, and Mask has the value
 RH> 10101010.

 RH> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
 RH> actually
 RH> 1111111101010101 (on the system we're assuming). When you & this with

Does it have something to do with alignment? Why is byte converted to int?

 RH> 00111101 (or rather, 0000000000111101) you get 0000000000010101, and
 RH> you then store this in an unsigned char, getting 00010101, which is
 RH> precisely what you want.

 RH> If your system has bigger bytes, bigger ints, or both, then you just
 RH> get more leading 0s to ignore. No big deal.

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply mrv (331) 11/17/2007 2:08:35 AM

Hello, Richard!
You wrote  on Fri, 16 Nov 2007 09:27:51 +0000:

 RH>>> If you thought ~Mask was 01010101, you'd be forgivably wrong. It's
 RH>>> actually
 RH>>> 1111111101010101 (on the system we're assuming). When you & this
 ??>>  with
 ??>>
 ??>> Does it have something to do with alignment? Why is byte converted to
 ??>> int?

 RH> On (possibly spurious) efficiency grounds.
Are these grounds declared by ANSI standard, is this conversion required to 
be done by every implementation? Could you tell me more about it or provide 
some links/hints.
Thanks.

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply mrv (331) 11/17/2007 2:36:25 AM

CBFalconer wrote:
> Roman Mashak wrote:
>> typedef struct {
>>         UCHAR Num;
>>         UCHAR Mask;
>>         UCHAR Val;
>> } IRVType, *PIRVType;
>> ...
>> bool SetIRVBit(PIRVType pIRV, UCHAR Num, UCHAR Mask, UCHAR Val)
>> {
>>    while (pIRV->Num || pIRV->Mask || pIRV->Val) {
>>       if (pIRV->Num!=Num) {
>>          pIRV++;
>>          continue;
>>       }
>>       pIRV->Mask|=Mask;
>>       pIRV->Val&=~Mask;
>>       pIRV->Val|=Val;
>>       return TRUE;
>>    }
>>    return FALSE;
>> }
>>
>> Compiling it with borland builder results with warning on "pIRV->Val&=~Mask"
>> line: "conversion may loose significant digits". Both operands are
>> (pIRV->Val and Mask) of the same type (UCHAR, which is 'unsigned char').
>> What's wrong with this snippet?
> 
> No they're not.  One is of the type ~Mask, which is an int.

You mean it's of the type *of* ~Mask.

> In addition, I believe your cavalier action of incrementing the
> pointer pIRV should be flagged as an error.  Pointers are not
> integers.

No, they certainly aren't, but incrementing a pointer is well defined.

> Thirdly, you are using the type 'bool'.  This implies the use of
> C99, and #include <stdbool.h>.  This also defines the standard
> values true and false (lower case).

No, it doesn't imply the use of C99.  "bool" is a valid identifier in 
C90.  For that matter, "bool" is a valid identifier in C99, particularly 
  if there's no "#include <stdbool.h>".  Probably the type "bool" and 
the identifiers (macros?) "FALSE" and "TRUE" are defined elsewhere.  (It 
would have been nice to see those declarations, and the declaration of 
UCHAR.)

-- 
Keith Thompson (The_Other_Keith) <kst-u@mib.org>
Looking for software development work in the San Diego area.
"We must do something.  This is something.  Therefore, we must do this."
     -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21469) 11/18/2007 8:06:12 AM

Roman Mashak wrote:
> Hello, Keith!
> You wrote  on Sun, 18 Nov 2007 00:06:12 -0800:
> 
>  ??>> Thirdly, you are using the type 'bool'.  This implies the use of
>  ??>> C99, and #include <stdbool.h>.  This also defines the standard
>  ??>> values true and false (lower case).
> 
>  KT> No, it doesn't imply the use of C99.  "bool" is a valid identifier in
>  KT> C90.  For that matter, "bool" is a valid identifier in C99,
>  KT> particularly if there's no "#include <stdbool.h>".  Probably the type
> I could not find stdbool.h neither in debian/linux nor in cygwin 
> environments.

It's on my Cygwin system (with gcc 3.4.4).  Perhaps you need to update 
your system.  (stdbool.h is provided by gcc, not as part of the C library.)

My Ubuntu 7.10 system (based on Debian) also has it (gcc 4.1.3).

But the only really topical thing to be said is that <stdbool.h> is 
required for any conforming C99 implementation, but is optional for any 
implementation that doesn't claim to conform to C99.

-- 
Keith Thompson (The_Other_Keith) <kst-u@mib.org>
Looking for software development work in the San Diego area.
"We must do something.  This is something.  Therefore, we must do this."
     -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21469) 11/19/2007 7:09:24 AM

Hello, Keith!
You wrote  on Sun, 18 Nov 2007 00:06:12 -0800:

 ??>> Thirdly, you are using the type 'bool'.  This implies the use of
 ??>> C99, and #include <stdbool.h>.  This also defines the standard
 ??>> values true and false (lower case).

 KT> No, it doesn't imply the use of C99.  "bool" is a valid identifier in
 KT> C90.  For that matter, "bool" is a valid identifier in C99,
 KT> particularly if there's no "#include <stdbool.h>".  Probably the type
I could not find stdbool.h neither in debian/linux nor in cygwin 
environments.

With best regards, Roman Mashak.  E-mail: mrv@tusur.ru 


0
Reply mrv (331) 11/19/2007 9:40:20 PM

Roman Mashak wrote:
> Keith Thompson wrote:
>> Charles Falconer wrote:
>> 
>>> Thirdly, you are using the type 'bool'.  This implies the use of
>>> C99, and #include <stdbool.h>.  This also defines the standard
>>> values true and false (lower case).
> 
>> No, it doesn't imply the use of C99.  "bool" is a valid identifier
>> in C90.  For that matter, "bool" is a valid identifier in C99,
>> particularly if there's no "#include <stdbool.h>".  Probably the
>
> I could not find stdbool.h neither in debian/linux nor in cygwin
> environments.

Please don't strip attributions.  I added some back in.

stdbool.h only exists for C99 implementations.  Yes, you can use
bool in C90 (and C99 when no stdbool.h is included), but such use
requires definition.  There was no such definition in the
originally quoted code (nor any possible #include).  To have
stdbool.h available you must at least (if using gcc) use "-std=c99"
in place of "ansi".  Then it depends on your installation.

-- 
 Chuck F (cbfalconer at maineline dot net)
   <http://cbfalconer.home.att.net>
   Try the download section.



-- 
Posted via a free Usenet account from http://www.teranews.com

0
Reply cbfalconer (19183) 11/20/2007 1:45:34 AM

CBFalconer wrote:
> Roman Mashak wrote:
>> Keith Thompson wrote:
>>> Charles Falconer wrote:
>>>
>>>> Thirdly, you are using the type 'bool'.  This implies the use of
>>>> C99, and #include <stdbool.h>.  This also defines the standard
>>>> values true and false (lower case).
>>> No, it doesn't imply the use of C99.  "bool" is a valid identifier
>>> in C90.  For that matter, "bool" is a valid identifier in C99,
>>> particularly if there's no "#include <stdbool.h>".  Probably the
>> I could not find stdbool.h neither in debian/linux nor in cygwin
>> environments.
> 
> Please don't strip attributions.  I added some back in.
> 
> stdbool.h only exists for C99 implementations.  Yes, you can use
> bool in C90 (and C99 when no stdbool.h is included), but such use
> requires definition.  There was no such definition in the
> originally quoted code (nor any possible #include).  To have
> stdbool.h available you must at least (if using gcc) use "-std=c99"
> in place of "ansi".  Then it depends on your installation.

In C90, <stdbool.h> is not a standard header; therefore a C90 compiler 
is allowed to provide it, as well as the _Bool keyword, as an extension.
(In fact, "gcc -std=c89" does so.)

The originally quoted code used at least one other identifier whose
definition was not shown.

-- 
Keith Thompson (The_Other_Keith) <kst-u@mib.org>
Looking for software development work in the San Diego area.
"We must do something.  This is something.  Therefore, we must do this."
     -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21469) 11/20/2007 10:34:23 AM

13 Replies
26 Views

(page loaded in 0.291 seconds)


Reply: