endian issue in type casting

If I typecast a byte to a long integer in different endian (Big &
Little endian) systems does it behave differently.

I am confused between the following.
If the address of the byte is 0 then seeing the address as long should
be different in big and little endian systems.
or
As the language is portable,long will have the same value when you see
it in little or big endian systems

Advertisements

On May 21, 10:14 am, Rupesh Kumar <> wrote:
> Hi,
>
> If I typecast a byte to a long integer in different endian (Big &
> Little endian) systems does it behave differently.
>
> I am confused between the following.
> If the address of the byte is 0 then seeing the address as long should
> be different in big and little endian systems.
> or
> As the language is portable,long will have the same value when you see
> it in little or big endian systems

Now it is appearing more clear to me.
1. If the char is typecast to long then the char value is get into
register and it will be assigned to the long variable so it should be
same in both endian systems.
2. As I was earlier thinking like if you see the address 0 in big and
endian systems it gives different values. This is also correct but
type casting doesnt care address of char.
Anyway typecasting char address to long pointer may make the long
pointer unaligned.

Advertisements

Rupesh Kumar <> writes:
> If I typecast a byte to a long integer in different endian (Big &
> Little endian) systems does it behave differently.

No. But first, some answers to questions you didn't ask.

The term is "cast", not "typecast". A cast is an operator, consisting
of a type name in parentheses, that specifies a conversion. And in
most cases, whatever conversion you want will be performed implicitly;
a cast is unnecessary and, in some cases, dangerous.

The value of foo will be 42. The representation of either char or
long is irrelevant. Conversions are defined to operate on values, not
on representations.
> I am confused between the following.
> If the address of the byte is 0 then seeing the address as long should
> be different in big and little endian systems.
> or
> As the language is portable,long will have the same value when you see
> it in little or big endian systems

Here, and in your followup, you talk about addresses, which makes me
wonder whether you're really asking about integer conversions (say,
from unsigned char to long) or about pointer conversions. Pointer
conversions can be used to implement what's called "type punning",
whereby an object of one type is treated as if it were of another
type. This does depend on the representation, and it can be dangerous
(and it's usually unnecessary). For example:

Here the code is looking at the object one_byte *as if* it were of
type long. Since it isn't, this can go bad in a number of ways. The
address of one_byte might not have the right alignment for type long,
and even if it's aligned correctly you're (almost certainly) looking
at bytes that aren't part of the object.

What are you actually trying to do?

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Rupesh Kumar <> wrote:
>If I typecast a byte to a long integer in different endian (Big &
>Little endian) systems does it behave differently.

It should be portable as the long can almost undoubtedly hold the value
in the char. It will be converted; endinnesss isn't an issue.

(Question for the pros: what if CHAR_BIT is 32, and unsigned char
0xffffffff is stored in a long where LONG_MAX is +2147483647?)
>I am confused between the following. If the address of the byte is 0
>then seeing the address as long should be different in big and little
>endian systems.

I'm a little confused by it, too. But I think maybe what you're getting
at is this:

unsigned short x = 0xff00; // two-byte shorts, say

On a little-endian system, this would be stored as bytes:

00 ff

while on a big-endian system, it would be stored as bytes:

ff 00

So now let's add some code:

unsigned short x = 0xff00;
unsigned char *p = (unsigned char *)&x;

printf("%02hhx\n", *p); // prints "00" on my little-endian system

The address of x converted to unsigned char * is the first byte of x,
and, as seen above, that can be 00 or ff depending on the machine's
endianness.

Beej Jorgensen <> writes:
> Rupesh Kumar <> wrote:
>>If I typecast a byte to a long integer in different endian (Big &
>>Little endian) systems does it behave differently.
>
> It should be portable as the long can almost undoubtedly hold the value
> in the char. It will be converted; endinnesss isn't an issue.
>
> (Question for the pros: what if CHAR_BIT is 32, and unsigned char
> 0xffffffff is stored in a long where LONG_MAX is +2147483647?)

The conversion yields an implementation-defined result or (new in C99)
raises an implementation-defined signal. C99 6.3.1.3p3.

[...]

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

> Here, and in your followup, you talk about addresses, which makes me
> wonder whether you're really asking about integer conversions (say,
> from unsigned char to long) or about pointer conversions. Pointer
> conversions can be used to implement what's called "type punning",
> whereby an object of one type is treated as if it were of another
> type. This does depend on the representation, and it can be dangerous
> (and it's usually unnecessary). For example:
>
> unsigned char one_byte = 42;
> unsigned char *byte_addr = &one_byte;
> long *long_addr = (long*)byte_addr; /* dangerous */
> long foo = *long_addr; /* dangerous */
>
> Here the code is looking at the object one_byte *as if* it were of
> type long. Since it isn't, this can go bad in a number of ways. The
> address of one_byte might not have the right alignment for type long,
> and even if it's aligned correctly you're (almost certainly) looking
> at bytes that aren't part of the object.
>
> What are you actually trying to do?
>
> --
> Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
> Nokia

I was talking about integer conversions only but I got confused it
with pointer conversions.
Your explanation clears all of my doubts.

On Wed, 20 May 2009 22:14:27 -0700 (PDT), Rupesh Kumar
<> wrote:
>Hi,
>
>If I typecast a byte to a long integer in different endian (Big &
>Little endian) systems does it behave differently.
>
>I am confused between the following.
>If the address of the byte is 0 then seeing the address as long should
>be different in big and little endian systems.
>or
>As the language is portable,long will have the same value when you see
>it in little or big endian systems
>
>Thanks
>Regards
>Rupesh Kumar

Wrong for two reasons.
Endian-ness is related to one target machine at a time. And the
machine hardware takes care of it in a consistent fashion (else it
would not work).
Any (very minor) endian-ness not already handled by the hardware is
done by the compiler at compile time, at a level well below the
written "C".
Q.E.D. There is no endian issue at the "C" level, on any one target
machine at any time.

this may give you UB as b may not be correctly aligned to be used
as a long.

This will give different behaviours depending on endianess

long ll = 1;
unsigned char b;

b = (unsigned char)ll;

printf ("%d\n", b);

may print either 0 or 1

> >I am confused between the following.
> >If the address of the byte is 0 then seeing the address as long should
> >be different in big and little endian systems.

yep
> >or
> >As the language is portable,long will have the same value when you see
> >it in little or big endian systems

yes but casting gets you to the underlying implementaion.
By casting something to unsigned char you get implementation
defined behaviour (casting to other things may get you
undefined behaviour- this *might* crash your program).

> Wrong for two reasons.

no. not wrong

> Endian-ness is related to one target machine at a time.

some hardware can change endianess on-the-fly. Though
I agree it's hard to see how a c impleemntaion could deal with this!
> And the
> machine hardware takes care of it in a consistent fashion (else it
> would not work).

no-ish
> Any (very minor) endian-ness

what is "minor endianess". Are only some of the bits endianised?
> not already handled by the hardware is
> done by the compiler at compile time, at a level well below the
> written "C".

no
> Q.E.D. There is no endian issue at the "C" level, on any one target
> machine at any time

Guest

> >>> >If I [cast] a byte to a long integer in different endian (Big &
> >>> >Little endian) systems does it behave differently.
>
> >> yes-ish though you might get Undefined Behaviour
>
> >> unsigned char b = 1;
> >> long ll;
>
> >> ll = (long)b;
>
> >> this may give you UB as b may not be correctly aligned to be used
> >> as a long.
>
> > Chapter and verse, please. Translation: I think you're talking
> > through your nose.

Or possibly some other bit of my anatomy
> > The value of b is 1, and 1 is in the range that can be represented
> > by a long, so casting it to long is harmless (and pointless). It
> > results in the value 1. Values do not *have* alignments, so
> > alignment is a non-issue here.
>
> Thank God for that.
>
> So Mr Keighley, a little egg to wipe off today after calling me a troll
> and then cocking up hugely only to be questioned on it by .... me.
>
> Enjoy that humble pie.

Egg and humble pie!

I was entirely wrong. I also owe JosephKK an apology.

What I was thinking of was this:-

long ll = 1;
unsigned char *b;

b = (unsigned char*)&ll;
printf ("%d\n", *b);

And for the record, richard <no-name>, I said you sometimes trolled.
Not that everything you said was wrong or technically uninteresting.

> >> >>> >If I [cast] a byte to a long integer in different endian (Big &
> >> >>> >Little endian) systems does it behave differently.
>
> >> >> yes-ish though you might get Undefined Behaviour
>
> >> >> unsigned char b = 1;
> >> >> long ll;
>
> >> >> ll = (long)b;
>
> >> >> this may give you UB as b may not be correctly aligned to be used
> >> >> as a long.
>
> >> > Chapter and verse, please. Translation: I think you're talking
> >> > through your nose.
>
> > Or possibly some other bit of my anatomy
>
> >> > The value of b is 1, and 1 is in the range that can be represented
> >> > by a long, so casting it to long is harmless (and pointless). It
> >> > results in the value 1. Values do not *have* alignments, so
> >> > alignment is a non-issue here.
>
> >> Thank God for that.
>
> >> So Mr Keighley, a little egg to wipe off today after calling me a troll
> >> and then cocking up hugely only to be questioned on it by .... me.
>
> >> Enjoy that humble pie.
>
> > Egg and humble pie!
>
> > I was entirely wrong. I also owe JosephKK an apology.
>
> > What I was thinking of was this:-
>
> > long ll = 1;
> > unsigned char *b;
>
> > b = (unsigned char*)&ll;
> > printf ("%d\n", *b);
>
> > And for the record, richard <no-name>, I said you sometimes trolled.
> > Not that everything you said was wrong or technically uninteresting.
>
> Little I have posted is "wrong" - only views based on my experiences.

It wasn't your views on technical matters I was characterising.

> My
> views on debuggers and those who are too cocksure to use them for
> example is just my view (and that of most good development managers I
> have worked with).

I didn't regard your opinion on debuggers as trolling.
And, I'm not in the set of people who never use debuggers.
I merely argue there is more than one way to skin a cat.

> Googling recently I found a post from Chucky I think
> it was claiming in that over 200 years (!) of programming C he had
> never had reason to use one.

They never did get gdb to work properly on the analytical engine.

> It says a lot more about him than it does
> about me I think. My views tend to be based on practical usage and not
> c.l.c based zealotry and desire to preen to the elite.
>
> Of more worry is how you got something so basic so very, very
> wrong. This suggests a passing knowledge of C at best.
>
> When I suggested I was possibly lax I was merely hooking you btw.
>
> Although fairs fair, you took it on the chin like a man

admitting you were wrong is, in my experience, easier than
trying to bullshit your way out of it.

On May 29, 9:24 am, wrote:
> On 29 May, 13:36, Richard <> wrote:
> > Googling recently I found a post from Chucky I think
> > it was claiming in that over 200 years (!) of programming C he had
> > never had reason to use one.
>
> They never did get gdb to work properly on the analytical engine.

Did they ever finish building that thing? Last I heard they had
completely given up on the printer. Is it even "Turing complete"?

Guest

On 30 May, 01:43, luserXtrog <> wrote:
> On May 29, 9:24 am, wrote:
>
> > On 29 May, 13:36, Richard <> wrote:
> > > Googling recently I found a post from Chucky I think
> > > it was claiming in that over 200 years (!) of programming C he had
> > > never had reason to use one.
>
> > They never did get gdb to work properly on the analytical engine.
>
> Did they ever finish building that thing? Last I heard they had
> completely given up on the printer. Is it even "Turing complete"?

I believe there never was a complete design for the analytical
engine. Only bits of it were constructed.I think it was fully
programmable and turing complete.

A modern replica of the difference engine was constructed by
the London Science Museum. The difference engine isn't
really programmable or TC. But you should try and see
it, it is so cool!

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!