L
Lorenzo J. Lucchini
My code contains this declaration:
: typedef union {
: word Word;
: struct {
: byte Low;
: byte High;
: } Bytes;
: } reg;
The colons are not part of the declaration.
Assume that 'word' is always a 16-bit unsigned integral type, and that
'byte' is always an 8-bit unsigned integral type ('unsigned short int'
and 'unsigned char' respectively on my implementation).
My understanding, after browsing through previous threads on this and
other newsgroup, is that given a variable Var of type reg, accessing
Var.Word after having assigned values to Var.Bytes.Low and
Var.Bytes.High or, conversely, accessing Var.Bytes.Low and
Var.Bytes.High after having assigned a value to Var.Word, results in
implementation-defined behavior (or possibly undefined behavior).
If it is indeed implementation-defined behavior, my question is: can
the implementation only take the liberty to choose whether
Var.Bytes.Low or Var.Bytes.High will contain the LSB of Var.Word, and
whether Var.Bytes.High or Var.Bytes.Low will contains the MSB, or can
the implementation take other liberties?
Intuitively, I would say that there is more than this (specifically,
that the compiler can insert padding after the first member of the
Bytes struct), but some articles I've read seemed to imply otherwise.
Anyway, it all comes down to: assume that I am willing to sacrifice
portability by forcing the maintainer to exchange the positions of the
two members of Bytes depending on the implementation; do I then have a
guarantee that Var.Bytes.Low will always evaluate to the LSB of
Var.Word, and that Var.Bytes.High will always evaluate to the MSB of
Var.Word?
If not, then I would gladly accept suggestions on how to change my
code.
Keep in mind that I need to access:
1) Var.Word (or its equivalent after the change) by address
2) Var.Bytes.Low (or its equivalent) by address
3) Var.Bytes.High (or its equivalent) by address
to the effect that this code can be modified in a straight-forward way
to work as intended:
: #include <stdlib.h>
: #include <stdio.h>
:
: int main() {
: reg Var;
: reg *VarWordP;
: reg *VarLSBP;
: reg *VarMSBP;
: VarWordP=&(Var.Word);
: VarLSBP=&(Var.Bytes.Low);
: VarMSBP=&(Var.Bytes.High);
: *VarWordP=0x1234;
: printf("%x %x %x\n", *VarWordP, *VarLSBP, *VarMSBP);
: return 0;
: }
Assume type reg has been defined as above. I should always get
1234 34 12
as the program's output, save any changes that could be needed in the
printf() format specifiers.
by LjL
(e-mail address removed)
: typedef union {
: word Word;
: struct {
: byte Low;
: byte High;
: } Bytes;
: } reg;
The colons are not part of the declaration.
Assume that 'word' is always a 16-bit unsigned integral type, and that
'byte' is always an 8-bit unsigned integral type ('unsigned short int'
and 'unsigned char' respectively on my implementation).
My understanding, after browsing through previous threads on this and
other newsgroup, is that given a variable Var of type reg, accessing
Var.Word after having assigned values to Var.Bytes.Low and
Var.Bytes.High or, conversely, accessing Var.Bytes.Low and
Var.Bytes.High after having assigned a value to Var.Word, results in
implementation-defined behavior (or possibly undefined behavior).
If it is indeed implementation-defined behavior, my question is: can
the implementation only take the liberty to choose whether
Var.Bytes.Low or Var.Bytes.High will contain the LSB of Var.Word, and
whether Var.Bytes.High or Var.Bytes.Low will contains the MSB, or can
the implementation take other liberties?
Intuitively, I would say that there is more than this (specifically,
that the compiler can insert padding after the first member of the
Bytes struct), but some articles I've read seemed to imply otherwise.
Anyway, it all comes down to: assume that I am willing to sacrifice
portability by forcing the maintainer to exchange the positions of the
two members of Bytes depending on the implementation; do I then have a
guarantee that Var.Bytes.Low will always evaluate to the LSB of
Var.Word, and that Var.Bytes.High will always evaluate to the MSB of
Var.Word?
If not, then I would gladly accept suggestions on how to change my
code.
Keep in mind that I need to access:
1) Var.Word (or its equivalent after the change) by address
2) Var.Bytes.Low (or its equivalent) by address
3) Var.Bytes.High (or its equivalent) by address
to the effect that this code can be modified in a straight-forward way
to work as intended:
: #include <stdlib.h>
: #include <stdio.h>
:
: int main() {
: reg Var;
: reg *VarWordP;
: reg *VarLSBP;
: reg *VarMSBP;
: VarWordP=&(Var.Word);
: VarLSBP=&(Var.Bytes.Low);
: VarMSBP=&(Var.Bytes.High);
: *VarWordP=0x1234;
: printf("%x %x %x\n", *VarWordP, *VarLSBP, *VarMSBP);
: return 0;
: }
Assume type reg has been defined as above. I should always get
1234 34 12
as the program's output, save any changes that could be needed in the
printf() format specifiers.
by LjL
(e-mail address removed)