* [9fans] portability question
@ 2010-06-16 9:11 hugo rivera
2010-06-16 10:01 ` Lucio De Re
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: hugo rivera @ 2010-06-16 9:11 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
Can someone clarify why the program included outputs 'AB000000' (as I
expect) on 32 bit systems and 'FFFFFFFFAB000000' on 64 bit systems?
where all those 1's came from? what's the portable way of doing this?
sorry for newbie questions like this.
unsigned long l;
unsigned char c;
l = 0L;
c = 0xAB;
l |= c << 24;
printf("%lX\n", l);
--
Hugo
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [9fans] portability question
2010-06-16 9:11 [9fans] portability question hugo rivera
@ 2010-06-16 10:01 ` Lucio De Re
2010-06-16 10:15 ` hugo rivera
2010-06-16 10:27 ` Charles Forsyth
2010-06-16 13:30 ` maht
2010-06-16 17:52 ` Bakul Shah
2 siblings, 2 replies; 8+ messages in thread
From: Lucio De Re @ 2010-06-16 10:01 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
On Wed, Jun 16, 2010 at 11:11:09AM +0200, hugo rivera wrote:
> printf("%lX\n", l);
Would you try %luX? It may work better?
++L
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [9fans] portability question
2010-06-16 10:01 ` Lucio De Re
@ 2010-06-16 10:15 ` hugo rivera
2010-06-16 10:27 ` Charles Forsyth
1 sibling, 0 replies; 8+ messages in thread
From: hugo rivera @ 2010-06-16 10:15 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
2010/6/16 Lucio De Re <lucio@proxima.alt.za>:
> On Wed, Jun 16, 2010 at 11:11:09AM +0200, hugo rivera wrote:
>
>> printf("%lX\n", l);
>
> Would you try %luX? It may work better?
no, or at least not as I intend. It produces '2868903936X' on 32 bit
linux and '18446744072283488256X' on 64 bit. According to printf(3),
an 'l' should work with both unsigned and signed long quantities.
--
Hugo
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [9fans] portability question
2010-06-16 10:01 ` Lucio De Re
2010-06-16 10:15 ` hugo rivera
@ 2010-06-16 10:27 ` Charles Forsyth
1 sibling, 0 replies; 8+ messages in thread
From: Charles Forsyth @ 2010-06-16 10:27 UTC (permalink / raw)
To: lucio, 9fans
>Would you try %luX? It may work better?
he's calling printf, not print
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [9fans] portability question
2010-06-16 9:11 [9fans] portability question hugo rivera
2010-06-16 10:01 ` Lucio De Re
@ 2010-06-16 13:30 ` maht
2010-06-16 15:26 ` erik quanstrom
2010-06-16 17:52 ` Bakul Shah
2 siblings, 1 reply; 8+ messages in thread
From: maht @ 2010-06-16 13:30 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
On 06/16/10 10:11, hugo rivera wrote:
> Can someone clarify why the program included outputs 'AB000000' (as I
> expect) on 32 bit systems and 'FFFFFFFFAB000000' on 64 bit systems?
> where all those 1's came from? what's the portable way of doing this?
> sorry for newbie questions like this.
>
>
> unsigned long l;
> unsigned char c;
>
> l = 0L;
> c = 0xAB;
> l |= c << 24;
> printf("%lX\n", l);
>
>
check the ASM, looks like c is being cast as signed and then sign
extended into a long and then ORed with l.
perhaps this would solve it :
l |= ((unsigned long) c) << 24
But I can't check
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [9fans] portability question
2010-06-16 13:30 ` maht
@ 2010-06-16 15:26 ` erik quanstrom
0 siblings, 0 replies; 8+ messages in thread
From: erik quanstrom @ 2010-06-16 15:26 UTC (permalink / raw)
To: maht-9fans, 9fans
> check the ASM, looks like c is being cast as signed and then sign
> extended into a long and then ORed with l.
>
> perhaps this would solve it :
>
> l |= ((unsigned long) c) << 24
that works. the extra () are unnecessary.
i think that gcc is using 6.3.1.1 and converting
c to an int (since it fits) so the original expression
is evaulated as
(int)0xab << (int)24
-> (int)0xab000000
if there is any sign extension here, it is shifted
away. then gcc sign-extends this into 8 bytes,
giving the value you see.
- erik
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [9fans] portability question
2010-06-16 9:11 [9fans] portability question hugo rivera
2010-06-16 10:01 ` Lucio De Re
2010-06-16 13:30 ` maht
@ 2010-06-16 17:52 ` Bakul Shah
2010-06-17 7:50 ` hugo rivera
2 siblings, 1 reply; 8+ messages in thread
From: Bakul Shah @ 2010-06-16 17:52 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
On Wed, 16 Jun 2010 11:11:09 +0200 hugo rivera <uair00@gmail.com> wrote:
> Can someone clarify why the program included outputs 'AB000000' (as I
> expect) on 32 bit systems and 'FFFFFFFFAB000000' on 64 bit systems?
> where all those 1's came from? what's the portable way of doing this?
> sorry for newbie questions like this.
>
>
> unsigned long l;
> unsigned char c;
>
> l = 0L;
> c = 0xAB;
> l |= c << 24;
> printf("%lX\n", l);
For use of C on non-plan9 machines I would recommend
downloading the last draft of the C9x standard as a ready
reference. Google for n843.
As per Section 6.5.7 of C9x, both operands of << must be of
"integer type" and the result type is that of the left
operand. Since sizeof c < sizeof(int), it is promoted. Now
6.3.1.2 says "if an int can represent all values of the
original type, the value is converted to an int". So c is
first converted to an int which means c << 24 is an integer
and -ve. Since an int is smaller than a long (in your case)
it is promoted to a long. Changing the |= statement to
l |= (unsigned)c << 24;
should give you what you want.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [9fans] portability question
2010-06-16 17:52 ` Bakul Shah
@ 2010-06-17 7:50 ` hugo rivera
0 siblings, 0 replies; 8+ messages in thread
From: hugo rivera @ 2010-06-17 7:50 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
Thanks for the feedback.
2010/6/16 Bakul Shah <bakul+plan9@bitblocks.com>:
> On Wed, 16 Jun 2010 11:11:09 +0200 hugo rivera <uair00@gmail.com> wrote:
>> Can someone clarify why the program included outputs 'AB000000' (as I
>> expect) on 32 bit systems and 'FFFFFFFFAB000000' on 64 bit systems?
>> where all those 1's came from? what's the portable way of doing this?
>> sorry for newbie questions like this.
>>
>>
>> unsigned long l;
>> unsigned char c;
>>
>> l = 0L;
>> c = 0xAB;
>> l |= c << 24;
>> printf("%lX\n", l);
>
> For use of C on non-plan9 machines I would recommend
> downloading the last draft of the C9x standard as a ready
> reference. Google for n843.
>
> As per Section 6.5.7 of C9x, both operands of << must be of
> "integer type" and the result type is that of the left
> operand. Since sizeof c < sizeof(int), it is promoted. Now
> 6.3.1.2 says "if an int can represent all values of the
> original type, the value is converted to an int". So c is
> first converted to an int which means c << 24 is an integer
> and -ve. Since an int is smaller than a long (in your case)
> it is promoted to a long. Changing the |= statement to
>
> l |= (unsigned)c << 24;
>
> should give you what you want.
>
>
--
Hugo
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-06-17 7:50 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-16 9:11 [9fans] portability question hugo rivera
2010-06-16 10:01 ` Lucio De Re
2010-06-16 10:15 ` hugo rivera
2010-06-16 10:27 ` Charles Forsyth
2010-06-16 13:30 ` maht
2010-06-16 15:26 ` erik quanstrom
2010-06-16 17:52 ` Bakul Shah
2010-06-17 7:50 ` hugo rivera
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 NNTP newsgroup(s).