How to extract bytes from a long?

C

CBFalconer

Joe said:
.... snip ...

I contend, as you seem to, that accessing u.lng as components of
u.byt[] is what unions are all about. We could be wrong.

You are. The purpose is to conserve storage space when only one
of a variety of facets of the object needs to be recorded.
Accessing memory through (unsigned char *) seems to be guaranteed
to work. I demonstrate both methods below. I don't understand why
the first is wrong while the second is right. Duck! :)

Again, this depends on the objective. If you want to examine all
the bits in the machine, including any padding or trap value bits,
yes. If you want to extract bits from the long value, no, because
they may well include bits extraneous to the value.
 
M

Mike Wahler

You should not assign new values to byt, that could cause trap
representations as you said, but reading is allowed and safe.

At first I too made similar unfounded assertions here,
due to my ignorance, but I *listened* when shown that
I was wrong.

-Mike
 
B

bd

cody said:
I'm suprised no one suggested a union!

#include <stdio.h>
union _x
{
long lng;
char byt[4];

Stop right here: what makes you think a long is four chars wide?

That could be easily overcome with sizeof. It's more that you can't
rely on
the byte order if you try to do it portably.

No, the problem is that you can't write into one union field and read
from another.


Isn't that what a union is good for???

They're intended as convenient ways of storing one out of several types in
one field. E.g., in a lexer or parser you might use something like:

struct token {
enum { TOKEN_FOO, TOKEN_BAR } type;
union {
struct token_foo_data foo;
struct token_bar_data bar;
} data;
};

Then, when processing the tokens, read the enum, and then read one of the
union fields based on the enum.
 
C

cody

#include said:
union _x
{
long lng;
char byt[sizeof long];
}
You should not assign new values to byt, that could cause trap
representations as you said, but reading is allowed and safe.

No it isn't. You have been told in another post that it is not.


When both variables in the union starts at the same address, writing to one
and reading from the other is safe.

Note the special guarantee:
[#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.68) 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
 
E

Eric Sosman

cody said:
When both variables in the union starts at the same address, writing to one
and reading from the other is safe.

Nonsense. *Every* variable in a union starts at the same
address (every addressable variable, that is: bit-fields have
no addresses as far as C is concerned).
Note the special guarantee:
[#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.68) 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

The special guarantee applies only to union members
that happen to be structs, and only to structs if they
"share a common initial subsequence." The union you
exhibited contained no structs at all, and is not covered
by the special guarantee.

Are you having trouble understanding the English in
which the Standard is written? You appear to be posting
from a .de address, which might indicate that your native
language is German. The great number of grammatical errors
in your written English makes me think you must be American,
but if not -- well, your English is better than my German,
but perhaps not equal to the task of deciphering Standardese.
 
A

Arthur J. O'Dwyer

As you have been told several times before, *don't snip attributions!*
They exist so that we can tell who said what.
char byt[sizeof (long)];
};
When both variables in the union starts at the same address, writing
to one and reading from the other is safe.

What part of "No it isn't" don't you understand? I think [whoever
that was] was *very* clear, and you can't claim misunderstanding
here.
Note the special guarantee:
[#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.

Boom. Implementation-defined. Sure, it's not undefined behavior,
but it's certainly not portable (which is what "safe" usually
connotes in the context of c.l.c).
68) 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

Right. Note the special guarantee.

It's nice that you've learned where to find the draft standard;
now if only you'd read it more carefully...

[Oh, and re the "4 bytes to 3 bytes" thread, you're wrong over there
too. Structure padding between bit-field members is implementation-
defined, and the standard says nothing about compiler switches.]

-Arthur
 
C

cody

Eric Sosman said:
Nonsense. *Every* variable in a union starts at the same
address (every addressable variable, that is: bit-fields have
no addresses as far as C is concerned).

union
{
int a;
struct
{
int b;
int c;
} X;
}

Note that a and c have different starting points. Bitfield does have an
address, while the bits they contain have not.
Note the special guarantee:
[#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.68) 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

The special guarantee applies only to union members
that happen to be structs, and only to structs if they
"share a common initial subsequence." The union you
exhibited contained no structs at all, and is not covered
by the special guarantee.

#include <stdio.h>
union X
{
struct { long lng} A;
struct { char byt[sizeof (long)] } B;
};

And now? Two structs with a common starting point.
Are you having trouble understanding the English in
which the Standard is written?

I try my best :)
You appear to be posting
from a .de address, which might indicate that your native
language is German.

That is correct, I'm german.
The great number of grammatical errors
in your written English makes me think you must be American,
but if not -- well, your English is better than my German,

I didn't know grammar of American and British is different.
but perhaps not equal to the task of deciphering Standardese.

Honestly, not a simple task. :)
 
C

cody

[Oh, and re the "4 bytes to 3 bytes" thread, you're wrong over there
too. Structure padding between bit-field members is implementation-
defined, and the standard says nothing about compiler switches.]

Does that mean in standard C you have no control over structure padding?
 
A

Arthur J. O'Dwyer

union
{
int a;
struct
{
int b;
int c;
} X; };

Note that a and c have different starting points.

Correct. Eric should have said, "Every *member* of a union starts
at the same address"; note that 'a' and 'X' have the same address.
Bitfield does have an
address, while the bits they contain have not.

Incorrect. One cannot take the address of a bit-field member.

The special guarantee applies only to union members
that happen to be structs, and only to structs if they
"share a common initial subsequence." The union you
exhibited contained no structs at all, and is not covered
by the special guarantee.

#include <stdio.h>
union X
{
struct { long lng} A;
struct { char byt[sizeof (long)] } B;
};

And now? Two structs with a common starting point.

And a common initial sequence of length zero. So you can write
zero bytes to &some_x.A, and read zero bytes from &some_x.B,
portably.

union Example {
struct { long x; } A;
struct { long y; long z; } B;
} ex;

Union 'Example' contains two structures with a common initial
sequence of length sizeof(long) bytes. Thus, one may portably
write to ex.A.x and then immediately read from ex.B.y, and
expect to get the same value back.

I didn't know grammar of American and British is different.

The fact that the great number of grammatical errors in your
written English made Eric think you must have been American,
makes me think Eric must be British. ;-)

-Arthur
 
S

Sheldon Simms

union
{
int a;
struct
{
int b;
int c;
} X;
}

Note that a and c have different starting points. Bitfield does have an
address, while the bits they contain have not.

'c' is not a "variable in a union". The two members of the union
are 'a' and 'X'.
Note the special guarantee:
[#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.68) 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

The special guarantee applies only to union members
that happen to be structs, and only to structs if they
"share a common initial subsequence." The union you
exhibited contained no structs at all, and is not covered
by the special guarantee.

#include <stdio.h>
union X
{
struct { long lng} A;
struct { char byt[sizeof (long)] } B;
};

And now? Two structs with a common starting point.

These two struct do not share a common initial sequence. The excerpt
from the standard above is talking about situations like this:

union U
{
struct {
int a;
int b;
char * p;
} A;
struct {
int x;
int y;
double d;
} B;
};

In both structs, the first few members are of the same type.
You may therefore do something like:

U.A.a = get_an_int();
put_an_int(U.B.x);
I try my best :)


That is correct, I'm german.


I didn't know grammar of American and British is different.

Jetzt weißt du. Aber ich glaube nicht, dass Eric von den
Grammatikunterschiede sprach, sondern dass Amerikaner zu
oft ihre eigene Muttersprache nur schlecht beherrschen.

Ãœbrigens, ich bin Amerikaner, also darf ich sowas sagen. :)
 
I

Irrwahn Grausewitz

cody said:
When both variables in the union starts at the same address, writing to one
and reading from the other is safe.

But only under very special circumstances, I already gave you a hint
in Message (e-mail address removed) .

Draft N??? 6.5.2.3 is what you quote, but it suspect you didn't read
it thoroughly, try again, please:
Note the special guarantee:
[#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.68) 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

Now, the question is: "Where are the structures in this thread?" :p

Regards
 
I

Irrwahn Grausewitz

cody said:
The special guarantee applies only to union members
that happen to be structs, and only to structs if they
"share a common initial subsequence." The union you
exhibited contained no structs at all, and is not covered
by the special guarantee.

#include <stdio.h>
union X
{
struct { long lng} A;
struct { char byt[sizeof (long)] } B;
};

And now? Two structs with a common starting point.

But still they do not "share a common initial sequence." Period.

Honestly, not a simple task. :)

True 'nough.
 
I

Irrwahn Grausewitz

Jetzt weißt du. Aber ich glaube nicht, dass Eric von den
Grammatikunterschiede sprach, sondern dass Amerikaner zu
oft ihre eigene Muttersprache nur schlecht beherrschen.

Übrigens, ich bin Amerikaner, also darf ich sowas sagen. :)

Did you ever read de.comp.lang.c? If so, what is your impression
about the skills of Germans regarding their native language? ;-)
 
S

Sheldon Simms

Did you ever read de.comp.lang.c?

I did
If so, what is your impression
about the skills of Germans regarding their native language? ;-)

I was so enthralled by the never-ending fights over whether people
have .signatures of the proper length, or have a valid email address
in their headers, or why one shouldn't use a nickname when posting,
etc., that I didn't have time to consider the grammar.

-Sheldon
 
M

Mike Wahler

cody said:
[Oh, and re the "4 bytes to 3 bytes" thread, you're wrong over there
too. Structure padding between bit-field members is implementation-
defined, and the standard says nothing about compiler switches.]

Does that mean in standard C you have no control over structure padding?

Correct. The only guarantee is that there is no padding
before the first member.

-Mike
 
M

Mike Wahler

Arthur J. O'Dwyer said:
The fact that the great number of grammatical errors in your
written English made Eric think you must have been American,
makes me think Eric must be British. ;-)

I took it to be a remark about the sad state of the American
education system, with which I would agree.

-Mike
 
T

those who know me have no need of my name

in comp.lang.c i read:
Does that mean in standard C you have no control over structure padding?

correct -- there is no standard mechanism available to control padding.
 
I

Irrwahn Grausewitz

Sheldon Simms said:
I did


I was so enthralled by the never-ending fights over whether people
have .signatures of the proper length, or have a valid email address
in their headers, or why one shouldn't use a nickname when posting,
etc., that I didn't have time to consider the grammar.

In fact those fights are the very reason why I read d.c.l.c [1], because
I enjoy to have some odd twenty jokes delivered daily for free, albeit
grammatically flawed ones. ;-)

I still wonder why they did not rename the group to d.c.l.c.flames yet.

[1] I do not bother to post there. To those who think c.l.c can be a
rough place: try d.c.l.c.

Irrwahn
 
C

cody

Arthur J. O'Dwyer said:
Incorrect. One cannot take the address of a bit-field member.

Sorry thereis a misunderstanding in terminology here. With bitfield i meant
struct X{int a:4;b:6;}x; And with "bits" and meant the members of the
bitfield. So we both were right :)
The special guarantee applies only to union members
that happen to be structs, and only to structs if they
"share a common initial subsequence." The union you
exhibited contained no structs at all, and is not covered
by the special guarantee.

#include <stdio.h>
union X
{
struct { long lng} A;
struct { char byt[sizeof (long)] } B;
};

And now? Two structs with a common starting point.

And a common initial sequence of length zero. So you can write
zero bytes to &some_x.A, and read zero bytes from &some_x.B,
portably.

union Example {
struct { long x; } A;
struct { long y; long z; } B;
} ex;

Union 'Example' contains two structures with a common initial
sequence of length sizeof(long) bytes. Thus, one may portably
write to ex.A.x and then immediately read from ex.B.y, and
expect to get the same value back.

Does that apply to my struct too? Iam not really sure wheather long and
char[sizeof(long)] are compatible in this situation.
The fact that the great number of grammatical errors in your
written English made Eric think you must have been American,
makes me think Eric must be British. ;-)

If you find a mistake in my postings please said whats wrong do that i can
do it better next time.
 

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,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top