Checking endianess in compile time

J

jlara

Having been stung by the same problem twice, I would like to
automatically check if the bitfields are regarded properly by the
compiler. For example, if I define the following structure:

typedef struct
{
unsigned int : 4;
unsigned int tffca : 1;
unsigned int tsfrz : 1;
unsigned int tswai : 1;
unsigned int ten : 1;
}tTSCR1;

Is there a way to check if the compiler considers bitfield ten to be
the most significant bit?

If there is, I would like to have the compiler give an error message (
#error ) and abort.

Thanks very much in advance.
 
G

Gordon Burditt

Having been stung by the same problem twice, I would like to
automatically check if the bitfields are regarded properly by the
compiler.

Bitfields *ARE* regarded properly by the compiler.
You may need to have your expecter fixed, though.
For example, if I define the following structure:

typedef struct
{
unsigned int : 4;
unsigned int tffca : 1;
unsigned int tsfrz : 1;
unsigned int tswai : 1;
unsigned int ten : 1;
}tTSCR1;

Is there a way to check if the compiler considers bitfield ten to be
the most significant bit?

Maybe (but not at compile time). Is this portable? Make a union
of an int and your bitfields. Assign to the bitfields, then look
at the int. Ordinarily that's not portable, but since bitfields
are supposed to be placed in (one or more) ints, does that work
under the "common first member" rule?
If there is, I would like to have the compiler give an error message (
#error ) and abort.

You cannot access memory at the preprocessor level. Therefore, you
can't check endianness unless you've got some header file which
tells you the endianness (and might be lying).

Gordon L. Burditt
 
K

Keith Thompson

jlara said:
Having been stung by the same problem twice, I would like to
automatically check if the bitfields are regarded properly by the
compiler. For example, if I define the following structure:

typedef struct
{
unsigned int : 4;
unsigned int tffca : 1;
unsigned int tsfrz : 1;
unsigned int tswai : 1;
unsigned int ten : 1;
}tTSCR1;

Is there a way to check if the compiler considers bitfield ten to be
the most significant bit?

If there is, I would like to have the compiler give an error message (
#error ) and abort.

I don't believe there's any way to check endianness at compilation
time. You can check it at run time. For example, declare a union of
the above struct and an unsigned char, check that sizeof(tTSCR1)
yields 1 and that CHAR_BIT==8, and for each named bit field, set the
unsigned char member to 0, set the bit field to 1, and check that the
unsigned char takes on the expected value. If any of these tests
fails, abort the program.

(Incidentally, "endianness" usually refers to the ordering of bytes
within a word; you're looking at bit order within a byte.)

If you don't want to perform this test every time the program runs,
you can incorporate it into your build procedure. Before building
your application, build and run a test program that performs the
appropriate tests; abort the build if the test program fails.
(Methods for doing this are off-topic; depending on your system, the
words "configure" and "Makefile" may provide a clue.)
 
S

Stephen Sprunk

jlara said:
Having been stung by the same problem twice, I would like to
automatically check if the bitfields are regarded properly by the
compiler. For example, if I define the following structure:

typedef struct
{
unsigned int : 4;
unsigned int tffca : 1;
unsigned int tsfrz : 1;
unsigned int tswai : 1;
unsigned int ten : 1;
}tTSCR1;

Is there a way to check if the compiler considers bitfield ten to be
the most significant bit?

If there is, I would like to have the compiler give an error message (
#error ) and abort.

Since you care about the exact representation of the bitfield, which is
difficult if not impossible to discover during preprocessing, might I
suggest simply using a char and some bitmasks (hidden behind macros) to
do the same thing?

/* warning, untested code */

#define SET_TFFCA(r) do { (*r) |= 0x10; } while(0)
#define CLR_TFFCA(r) do { (*r) &= 0xef; } while (0)
#define SET_TSFRZ(r) do { (*r) |= 0x20; } while (0)
#define CLR_TSFRZ(r) do { (*r) &= 0xdf; } while (0)
#define SET_TSWAI(r) do { (*r) |= 0x40; } while(0)
#define CLR_TSWAI(r) do { (*r) &= 0xbf; } while (0)
#define SET_TEN(r) do { (*r) |= 0x80; } while(0)
#define CLR_TEN(r) do { (*r) &= 0x7f; } while (0)

And, of course, you'll need to check that CHAR_BIT == 8.

Then you can do:

char *hwreg = (location);
SET_TFFCA(hwreg);
CLR_TEN(hwreg);

S
 
C

CBFalconer

jlara said:
Having been stung by the same problem twice, I would like to
automatically check if the bitfields are regarded properly by the
compiler. For example, if I define the following structure:

typedef struct
{
unsigned int : 4;
unsigned int tffca : 1;
unsigned int tsfrz : 1;
unsigned int tswai : 1;
unsigned int ten : 1;
}tTSCR1;

Is there a way to check if the compiler considers bitfield ten
to be the most significant bit?

If there is, I would like to have the compiler give an error
message ( #error ) and abort.

The DS9000 system will site the 'ten' field anywhere from first to
last, dependant on the day of the week modulo some ramdom number.
In other words, if it matters, use another method, such as explicit
masks.
 
L

Lawrence Kirby

I'm not sure what you mean by "properly". There are various choices a
compiler can legitimately make in allocating bits for bits-fields.

There isn't even a guarantee that this will allocate 1 byte. Many
compilers will allocate a word (e.g. 32 bits) for this.

Why not just write code that works anyway? Bit-fields are designed to
create small integer objects, they aren't well suited to bit level layouts.
Use bit manipulations on, say, an unsigned char instead.
difficult if not impossible to discover during preprocessing, might I
suggest simply using a char and some bitmasks (hidden behind macros) to
do the same thing?

/* warning, untested code */

#define SET_TFFCA(r) do { (*r) |= 0x10; } while(0)
#define CLR_TFFCA(r) do { (*r) &= 0xef; } while (0)
#define SET_TSFRZ(r) do { (*r) |= 0x20; } while (0)
#define CLR_TSFRZ(r) do { (*r) &= 0xdf; } while (0)
#define SET_TSWAI(r) do { (*r) |= 0x40; } while(0)
#define CLR_TSWAI(r) do { (*r) &= 0xbf; } while (0)
#define SET_TEN(r) do { (*r) |= 0x80; } while(0)
#define CLR_TEN(r) do { (*r) &= 0x7f; } while (0)

do { } whole (0) is a useful construct in macros but not needed for single
expressions. It is simpler and clearer to write

#define SET_TFFCA(r) ((*r) |= 0x10)

etc.

Lawrence
 
B

baumann@pan

1)
what do you all think a variable defined as
char c_var = 'a';
would be read in another environment?

i think it must be 'a' ,right?

2)
thus,
there is no need to talk about the problem of bit-field's endian.

3)
and we only need to know the architecture's endian mode.
 
M

Michael Mair

Umh, what are you replying to? Even though I can see the
"upwards" message, I am not sure which part(s) your questions
belong.
Please quote a sensible amount of context so everybody knows
what you are referring to.

baumann@pan said:
1)
what do you all think a variable defined as
char c_var = 'a';
would be read in another environment?

i think it must be 'a' ,right?

Execution environment?
Translation environment?
Floating point environment?
Host environment?
Hosted/freestanding environment?
Environment in the sense of longjmp()/setjmp()?

The latter is the closest to making sense for me but probably
you are using environment in another sense.

2)
thus,
there is no need to talk about the problem of bit-field's endian.

3)
and we only need to know the architecture's endian mode.

I am still not sure what you are talking about but char and bitfields
have nothing to do with each other unless your implementation supports
char-bitfields as an extension.
Do you wish to replace bitfields by _unsigned_ char as suggested by
other people?
Maybe you really added a new aspect to the discussion but I
completely miss it.


Cheers
Michael
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top