On 27 Nov 2003 20:34:04 -0800,
in*******@yahoo.com (Sushil) wrote in
comp.lang.c:
hi Gurus
I'm a newbie learning C.
I've a question, relevant code snippet is as follows :
typedef unsigned long long ulonglong;
struct foo {
unsigned dummy : 2;
unsigned n : 24;
unsigned c : 3;
unsigned d : 1;
unsigned v : 1;
unsigned g : 1;
};
ulonglong func_foo(void) {
ulonglong addr;
struct foo entry;
/* code that populates entry snipped*/
addr = entry.n << 12;
This is a problem, due to C's value preserving promotion rules.
Assuming ints have more than 24 bits on your platform, the unsigned
value in entry.n is converted to a signed int, then left shifted 12
times producing a signed int value. If your ints have 32 bits, the
top four bits of entry.n are shifted off the end and disappear.
.
.
}
This caused sign extended value in addr which is not we want.
Would the following be a good fix or clc gurus have a better suggestion?
addr = ((ulonglong)entry.n) << 12;
This will work just fine. The 24 bits in entry.n will be placed in
the lowest 24 bits of an unsigned long long. No sign extension will
occur, and there is no possibility of overflow.
I'm concerned that there is more to it than what I feel the fix is.
Thanks in advance
- Sushil
There are ways to define a union consisting of a bit-mapped structure
and an unsigned long long, but doing it with the cast is more portable
and doesn't need to be modified if any of the bit-fields change size,
position, or are added or deleted.
--
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