conversion

R

Richard Heathfield

Roman Mashak said:

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

Richard Heathfield

Roman Mashak said:

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

Richard Heathfield

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".
 
E

Eric Sosman

Richard said:
Roman Mashak said:



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

Richard Heathfield

Eric Sosman said:
... 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.
 
C

CBFalconer

Roman said:
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).
 
R

Roman Mashak

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: (e-mail address removed)
 
R

Roman Mashak

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: (e-mail address removed)
 
R

Roman Mashak

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: (e-mail address removed)
 
K

Keith Thompson

CBFalconer said:
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.)
 
K

Keith Thompson

Roman said:
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.
 
R

Roman Mashak

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: (e-mail address removed)
 
C

CBFalconer

Roman said:
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.
 
K

Keith Thompson

CBFalconer said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top