endian issue in type casting

R

Rupesh Kumar

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
 
R

Rupesh Kumar

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.

Correct me if I am wrong.

Thanks
Regards
Rupesh Kumar
 
K

Keith Thompson

Rupesh Kumar said:
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.

For example:

unsigned char one_byte = 42;
long foo = one_byte; /* implicit conversion from unsigned char to long */

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:

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?
 
B

Beej Jorgensen

Rupesh Kumar said:
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
 
K

Keith Thompson

Beej Jorgensen said:
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.

[...]
 
R

Rupesh Kumar

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?


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

Thanks a lot.

Regards
Rupesh Kumar
 
J

JosephKK

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

Guest

On Wed, 20 May 2009 22:14:27 -0700 (PDT), Rupesh Kumar
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.

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


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

define "C level". You are misleading a newbie.
 
G

Guest

Richard Heathfield said:
(e-mail address removed) said:
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
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*)≪
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.
 
K

Keith Thompson

Keith Thompson said:
The term is "cast", not "typecast".

I stand corrected.

You used "type casting", which has precedent in the Rationale.

Sorry to be a bother. =) Ignore the rest of my post as well.
 
K

Keith Thompson

long ll = 1;
unsigned char *b;

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

How is undefined behavior on the DS9K helpful? Please quit jerking
us around, or I will killfile you.
 
G

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

luserXtrog

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"?
 
G

Guest

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!

I'm not sure about the printer
 

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,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top