conversion

R

Roopa

Hi,

I have written a program to know whether a system is little/big endian,
Is this correct/generic.

#include <stdio.h>

int main ()
{
int i = 1;

if (*(char *)&i == 1 )
printf ("Little Endian\n");
else
printf ("BIG Endian\n");
return 0;
}

Thanks,
- Roopa
 
N

Neo

Hi,

U can do it like this also :

union ABYTE {
char ch;
int i;
} aByte;

int main()
{
aByte.i = 1;
if(aByte.ch)
printf ("Little Endian\n");
else
printf ("BIG Endian\n");

return 0;
}

-Neo
 
N

Neo

Roopa said:
Hi,

I have written a program to know whether a system is little/big endian,
Is this correct/generic.

#include <stdio.h>

int main ()
{
int i = 1;

if (*(char *)&i == 1 )
printf ("Little Endian\n");
else
printf ("BIG Endian\n");
return 0;
}

Thanks,
- Roopa

Yes, its O'kay.
-Neo
 
T

Trent Buck

Quoth Roopa on or about 2004-11-23:
I have written a program to know whether a system is little/big endian,
Is this correct/generic.

It's the test described in the clc faq, so presumably it is correct.

http://www.eskimo.com/~scs/C-faq/q20.9.html

I prefer to put it into a function.

int
little_endian_p (void)
{
int x = 1;
return 1 == *(char *)&x;
}

I think the FAQ also mentions that

* It's better to write code that doesn't care.
* Architectures can be neither little- nor big-endian.

-trent
 
P

pete

Neo said:
Hi,

U can do it like this also :

union ABYTE {
char ch;
int i;
} aByte;

int main()
{
aByte.i = 1;
if(aByte.ch)

Whether or not that works, is implementation defined.

N869
6.5.2.3 Structure and union members
[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined. One special guarantee is made in
order to simplify the use of unions: If a union contains
several structures that share a common initial sequence (see
below), and if the union object currently contains one of
these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of
the completed type of the union is visible. Two structures
share a common initial sequence if corresponding members
have compatible types (and, for bit-fields, the same widths)
for a sequence of one or more initial members.
 
J

Jack Klein

Hi,

I have written a program to know whether a system is little/big endian,
Is this correct/generic.

#include <stdio.h>

int main ()
{
int i = 1;

if (*(char *)&i == 1 )
printf ("Little Endian\n");
else
printf ("BIG Endian\n");
return 0;
}

Thanks,
- Roopa

Actually it results in undefined behavior according to the C standard.
If you replaces the (char *) cast with (unsigned char *), at least
there is no undefined behavior, and the code will do what you want on
most common desktop platforms.

But there are other architectures, mostly digital signal processors,
where it most certainly will not provide the result you expect.
 
N

Neo

pete said:
Neo said:
Hi,

U can do it like this also :

union ABYTE {
char ch;
int i;
} aByte;

int main()
{
aByte.i = 1;
if(aByte.ch)

Whether or not that works, is implementation defined.

N869
6.5.2.3 Structure and union members
[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined. One special guarantee is made in
order to simplify the use of unions: If a union contains
several structures that share a common initial sequence (see
below), and if the union object currently contains one of
these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of
the completed type of the union is visible. Two structures
share a common initial sequence if corresponding members
have compatible types (and, for bit-fields, the same widths)
for a sequence of one or more initial members.

Heyyyy pete,

Where can I found the C Specification, which U have commented above?

Thnx,

-Neo
 
N

Neo

Neo said:
Yes, its O'kay.
-Neo

Sorry, this method will not work on all architecture.
I tried it on TMS320C5402 DSP and it miserably failed, coz on it word length
is 16-bit, so, CHAR and INT both are of 16-bits. Could anyone suggest some
portrable way for the same?

-Neo
 
N

Neo

pete said:
Neo said:
Hi,

U can do it like this also :

union ABYTE {
char ch;
int i;
} aByte;

int main()
{
aByte.i = 1;
if(aByte.ch)

Whether or not that works, is implementation defined.

N869
6.5.2.3 Structure and union members
[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined.

If it's not permissible to write to one member of the Union and read back
from another member of the Union, what is the use of the a UNION then? I
think this one the most common uses of a UNION, isn't it?
One special guarantee is made in
order to simplify the use of unions: If a union contains
several structures that share a common initial sequence (see
below), and if the union object currently contains one of
these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of
the completed type of the union is visible. Two structures
share a common initial sequence if corresponding members
have compatible types (and, for bit-fields, the same widths)
for a sequence of one or more initial members.

-Neo
 
R

Randy Howard

If it's not permissible to write to one member of the Union and read back
from another member of the Union, what is the use of the a UNION then?

Use the space for more than one purpose, in a managed fashion. You must
keep track so that you don't misuse it.
I think this one the most common uses of a UNION, isn't it?

Probably, which is a sad commentary on "common" programmers, nothing more.
 
M

Michael Mair

Neo said:
Neo said:
Hi,

U can do it like this also :

union ABYTE {
char ch;
int i;
} aByte;

int main()
{
aByte.i = 1;
if(aByte.ch)

Whether or not that works, is implementation defined.

N869
6.5.2.3 Structure and union members
[#5] With one exception, if the value of a member of a union
object is used when the most recent store to the object was
to a different member, the behavior is
implementation-defined.


If it's not permissible to write to one member of the Union and read back
from another member of the Union, what is the use of the a UNION then? I
think this one the most common uses of a UNION, isn't it?

Nope. The most common use is to confuse people who do not think
things through ;-)

In a structure, you gather data which belongs together logically
and has to be present all at once. In a union, you store data
which is logically equivalent but the situations where union members
are used are mutually exclusive.
Example:
union {
double binaryfraction;
struct {
int numerator;
int denominator;
} symbolicfraction;
} fraction;
If you are in the symbolic context, you use the symbolicfraction
and do not lose anything; if the symbolic fractions no longer can
express the numbers, you go over to floating point numbers. As both
representations at once would waste memory, you just put them
together. Now, you only have to mind the context... (see below)

.... which is provided for by the above.
union {
struct {
int type;
} generic;
struct {
int type;
double fpdata;
} binaryfraction;
struct {
int type;
int numerator;
int denominator;
} symbolicfraction;
} fraction;

Now, you can also store the type of fraction within the union, access
it via generic.type and will automatically know binaryfraction.type
and symbolicfraction.type, as it has to be the same.
With the right sort of access macros (one set for reading, one for
writing), this is still manageable.


If you use a union to access some "bit pattern" by different data types,
you can run into different problems:
- trap representations: There are bit patterns which are not valid
for one type but for the other.
- the compiler optimised access to a certain union member by putting
it or parts of it into registers and if you access another union
member, you will not work with the actual representation but the
last stored.
- ... (too lazy to list all I can think of :))


Cheers
Michael
 
S

S.Tobias

Jack Klein said:
On 23 Nov 2004 00:22:04 -0800, (e-mail address removed) (Roopa) wrote in
comp.lang.c:
Actually it results in undefined behavior according to the C standard.
If you replaces the (char *) cast with (unsigned char *), at least
there is no undefined behavior, and the code will do what you want on
most common desktop platforms.

I do not understand why (and I've heard an been confused by this
hearsay at other places, too):

6.5 Expressions
[#7] An object shall have its stored value accessed only by
an lvalue expression that has one of the following types:63)
[...]
-- a character type.

This is also indirectly repeated in 6.2.6.1#5 and in appendix J.2
(first "trap" hit, in n869.txt) in sense that they don't exclude
other types than unsigned char.

A "character type" includes all: char, signed char and unsigned char.
 
K

Keith Thompson

Neo said:
Sorry, this method will not work on all architecture.
I tried it on TMS320C5402 DSP and it miserably failed, coz on it word length
is 16-bit, so, CHAR and INT both are of 16-bits. Could anyone suggest some
portrable way for the same?

How did it fail, and what do you want it to do?

Endianness is about whether, for example, the bytes composing an
integer value are stored low-order first or high-order first. If an
integer is only one byte long, it has no endianness. (If it's a
comforming implementation, there should be a type long that's a least
32 bits; it probably makes sense to ask about the endianness of type
long.)

BTW, it probably makes more sense to use unsigned types for this kind
of thing.
 
C

Chris Torek

int i = 1;
if (*(char *)&i == 1 )
[/QUOTE][/QUOTE]

I do not understand why (and I've heard an been confused by this
hearsay at other places, too):

6.5 Expressions
[#7] An object shall have its stored value accessed only by
an lvalue expression that has one of the following types:63)
[...]
-- a character type.

This is also indirectly repeated in 6.2.6.1#5 and in appendix J.2
(first "trap" hit, in n869.txt) in sense that they don't exclude
other types than unsigned char.

A "character type" includes all: char, signed char and unsigned char.

I *think* the problem here is that, while the clause you quote here
does not render the behavior undefined, other clauses may. In
particular, if plain char has padding bits, you can get undefined
behavior; or, for sign-and-magnitude or ones' complement systems,
if the sign bit is set, you can get -0, which is allowed to "behave
badly".

(This is perhaps worth bringing up in comp.std.c. The text may be
written as desired, given that plain char can be either signed or
unsigned, yet remains a distinct type from unsigned char even when
it is unsigned.)
 
N

Neo

Keith Thompson said:
How did it fail, and what do you want it to do?

Endianness is about whether, for example, the bytes composing an
integer value are stored low-order first or high-order first. If an
integer is only one byte long, it has no endianness. (If it's a
comforming implementation, there should be a type long that's a least
32 bits; it probably makes sense to ask about the endianness of type
long.)

ya, long is 32-bits.

-Neo
 
L

Lawrence Kirby

Quoth Roopa on or about 2004-11-23:

It's the test described in the clc faq, so presumably it is correct.

Maybe not. Changing ther cast to unsigned char * would certainly be an
improvement.
http://www.eskimo.com/~scs/C-faq/q20.9.html

I prefer to put it into a function.

int
little_endian_p (void)
{
int x = 1;
return 1 == *(char *)&x;
}

I think the FAQ also mentions that

* It's better to write code that doesn't care.
* Architectures can be neither little- nor big-endian.

Absolutely, it is usually possible to write code that works without making
assumptions about the underlying byte order.

Lawrence
 

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
474,155
Messages
2,570,871
Members
47,401
Latest member
CliffGrime

Latest Threads

Top