Macro for setting MSB - Intended to work on both Little and Bigendian machines

M

Myth__Buster

Hi All,

Here is my attempt for setting the MSB of an integer depending upon whetherthe underlying machine is Little or Big-endian. Any comments/suggestions/views are appreciated.

Here I have assumed though I don't store the 1LL(LL - long long - to force 1 to be stored in a multiple memory resource(say register) to hold the value 1) in a variable in my program, it will be accessed as a multi-byte valueand hence 1 will be stored in the LSB of most-significant-byte of the memory resource(say register) and not in the LSB of least-significant-byte of that resource. Please let me know if this is correct.

Code:

#include <stdio.h>
#include <limits.h>

#define LSET_MSB(x) ((x) = (x) | 1 << sizeof(x) * CHAR_BIT - 1)

#define BSET_MSB(x) ((x) = (x) | 1 << CHAR_BIT - 1)

#define LIITE_ENDIAN (1LL & 1)

int main(void)
{
int x = 1;

printf("x : %d\n", x);

if ( LIITE_ENDIAN )
{
printf("Little\n");
LSET_MSB(x);
}
else
{
printf("Big\n");
BSET_MSB(x);
}

printf("x : %d\n", x);

return 0;
}


Cheers,
Raghavan
 
B

Bart van Ingen Schenau

Hi All,

Here is my attempt for setting the MSB of an integer depending upon
whether the underlying machine is Little or Big-endian. Any
comments/suggestions/views are appreciated.

Here I have assumed though I don't store the 1LL(LL - long long - to
force 1 to be stored in a multiple memory resource(say register) to hold
the value 1) in a variable in my program, it will be accessed as a
multi-byte value and hence 1 will be stored in the LSB of
most-significant-byte of the memory resource(say register) and not in
the LSB of least-significant-byte of that resource. Please let me know
if this is correct.

If I understand correctly what you mean, then no, that is not correct.
In C, you don't have to deal with endianness except in the very specific
situation where, in your program, you have to convert a value of type X
to a sequence of bytes in a particular endianness or vice versa.
In particular, all arithmetic and bitwise operations are specified in
such a way that the result does not depend in any way on how a type is
split into bytes nor on how those bytes might be ordered in memory.
Code:

#include <stdio.h>
#include <limits.h>

#define LSET_MSB(x) ((x) = (x) | 1 << sizeof(x) * CHAR_BIT - 1)

This macro will set the most significant bit of x regardless of how large
x is or how x is stored in memory.
#define BSET_MSB(x) ((x) = (x) | 1 << CHAR_BIT - 1)

This macro will set the most significant bit of the least significant
byte of x regardless of how large x is or how x is stored in memory.
#define LIITE_ENDIAN (1LL & 1)

This macro is identical to
#define LIITE_ENDIAN (1)
It just tests is the values 1 and 1 have at least one bit set in common,
which is true by definition.
int main(void)
{
int x = 1;

printf("x : %d\n", x);

if ( LIITE_ENDIAN )
{
printf("Little\n");
LSET_MSB(x);
}
else
{
If you set the warning level high enough, your compiler might even warn
you that this branch can never be taken.
printf("Big\n");
BSET_MSB(x);
}

printf("x : %d\n", x);

return 0;
}


Cheers,
Raghavan

Bart v Ingen Schenau
 
M

Myth__Buster

If I understand correctly what you mean, then no, that is not correct.

In C, you don't have to deal with endianness except in the very specific

situation where, in your program, you have to convert a value of type X

to a sequence of bytes in a particular endianness or vice versa.

In particular, all arithmetic and bitwise operations are specified in

such a way that the result does not depend in any way on how a type is

split into bytes nor on how those bytes might be ordered in memory.







This macro will set the most significant bit of x regardless of how large

x is or how x is stored in memory.







This macro will set the most significant bit of the least significant

byte of x regardless of how large x is or how x is stored in memory.







This macro is identical to

#define LIITE_ENDIAN (1)

It just tests is the values 1 and 1 have at least one bit set in common,

which is true by definition.





If you set the warning level high enough, your compiler might even warn

you that this branch can never be taken.






Bart v Ingen Schenau

Hi,

Well, I had to edit my question couple of times. Here is the correct one - https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.c/5jgv9EqggKI
Please follow there.

Cheers.
 
L

Les Cargill

Bart said:
If I understand correctly what you mean, then no, that is not correct.
In C, you don't have to deal with endianness except in the very specific
situation where, in your program, you have to convert a value of type X
to a sequence of bytes in a particular endianness or vice versa.

The "specific situation" is almost always
described as "needing to conform to network byte order".
In particular, all arithmetic and bitwise operations are specified in
such a way that the result does not depend in any way on how a type is
split into bytes nor on how those bytes might be ordered in memory.
<snip>
 
K

Keith Thompson

Myth__Buster said:
Well, I had to edit my question couple of times. Here is the correct
one -
https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.c/5jgv9EqggKI
Please follow there.

You're posting to Usenet via the Google Groups interface.
Google does some things well, but their Usenet interface is not
one of them. Most of us read this newsgroup using NNTP-capable
newsreader programs, which have nothing to do with Google.

Some guidelines for posting here (which GG makes unnecessarily
difficult):

Keep your lines under 80 columns, preferably under 72. Not all
newsreader programs deal with with very long lines. (Mine, for
example, doesn't wrap at word boundaries.)

When posting a followup, quote the previous article, but only
enough of it for your followup to make sense. GG has a bug that
causes it to double-space quoted text. Consider copy-and-pasting
your post into a text editor, cleaning it up, and copy-and-pasting
it back to your web browser before posting.

You can't edit a post once you've hit "send" (or whatever your
equivalent is); you can only post a new article or a followup.
Don't change the subject line unnecessarily. If you need to correct
an article, do it as a followup.

Consider getting an actual newsreader program (I use Gnus, which
runs under Emacs; Mozilla Thunderbird also works) and an account
on a news server (I use news.eternal-september.org, which is free
and works pretty well).
 
G

glen herrmannsfeldt

Les Cargill said:
Bart van Ingen Schenau wrote: (snip)
The "specific situation" is almost always
described as "needing to conform to network byte order".

In that case, something like:

if(ntohl(1)==1)

should work. (With the appropriate #include file.)

-- glen
 
J

Jorgen Grahn

.
In C, you don't have to deal with endianness except in the very specific
situation where, in your program, you have to convert a value of type X
to a sequence of bytes in a particular endianness or vice versa.

And even then you don't have to deal with endianness in the sense of
"what's the internal structure of an int?". Untested example:

void put16_bigendian(unsigned n, uint8_t* dest)
{
*dest++ = n >> 8;
*dest++ = n;
}

Certain APIs /force/ you to deal with it, e.g. the BSD socket API
which gives you IP addresses and UDP or TCP port numbers as
big-endian quantities.

/Jorgen
 
M

Martin Shobe

This macro will set the most significant bit of x regardless of how large
x is or how x is stored in memory.

As far as I can tell, this would encounter undefined behavior if 1 <<
sizeof(x) * CHAR_BIT - 1 exceeds INT_MAX, which will happen if sizeof(x)
= sizeof(int).

Better would be to use

#include <stdint.h>

#define LSET_MSB(x) ((x) = (x) | (uintmax_t) 1 << sizeof(x) * CHAR_BIT - 1)

Martin Shobe
 
C

Correador UK

As far as I can tell, this would encounter undefined behavior if 1 <<
sizeof(x) * CHAR_BIT - 1 exceeds INT_MAX, which will happen if sizeof(x)
 >= sizeof(int).

Better would be to use

#include <stdint.h>

#define LSET_MSB(x) ((x) = (x) | (uintmax_t) 1 << sizeof(x) * CHAR_BIT - 1)

I'd consider using (INT_MAX >> 1) + 1 as a way to get the MSB. No
worries about overflow, sizes or padding bits.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top