9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [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).