Open gpeterhoff opened 1 year ago
The last example looks like the first example. Why you think it would work differently?
https://www.boost.org/doc/libs/1_82_0/boost/predef/other/endian.h
#if BOOST_ENDIAN_BIG_BYTE
# define BOOST_ENDIAN_BIG_BYTE_AVAILABLE
#endif
#if BOOST_ENDIAN_BIG_WORD
# define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE
#endif
#if BOOST_ENDIAN_LITTLE_BYTE
# define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE
#endif
#if BOOST_ENDIAN_LITTLE_WORD
# define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE
#endif
#define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian"
#define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian"
#define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian"
#define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian"
You have overlooked the UNIQUE in the macro. In the first example, as I said, several cases can occur in the else branch:
With the UNIQUE-macros these ambiguities are excluded.
thx & regards Gero
You have overlooked the UNIQUE in the macro.
I am not.
With the UNIQUE-macros these ambiguities are excluded.
It still not clear how.
If you wrote something like:
#if defined(BOOST_ENDIAN_LITTLE_BYTE_LITTLE_WORD_LITTLE_DWORD_LITTLE_QWORD_BLABLABLA_AVAILABLE)
then, it would be more unique.
I thought my (brief) comments would be sufficient. But I would like to explain it to you in detail:
// WORD ?
BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE or BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE is available - independent of BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE or BOOST_ENDIAN_BIG_BYTE_AVAILABLE
// BYTE ?
BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE or BOOST_ENDIAN_BIG_BYTE_AVAILABLE is available - independent of BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE or BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE
// unique WORD or BYTE ?
(!defined(BOOST_ENDIAN_WORD_AVAILABLE) && defined(BOOST_ENDIAN_BYTE_AVAILABLE)) / BYTE only /
BOOST_ENDIAN_UNIQUE_AVAILABLE is defined only if BOOST_ENDIAN_WORD_AVAILABLE or BOOST_ENDIAN_BYTE_AVAILABLE is defined - exclusive or. If both/no definitions exist, BOOST_ENDIAN_UNIQUE_AVAILABLE is not defined. This makes it possible to clearly distinguish whether the endianness is WORD- or BYTE-based.
// unique WORD
helper, is only defined if the unique endianness is WORD-based
// unique BYTE
helper, is only defined if the unique endianness is BYTE-based
// unique LITTLE_WORD
is only defined if the unique endianness is WORD-based and LITTLE_WORD
// unique BIG_WORD
is only defined if the unique endianness is WORD-based and BIG_WORD
This can rule out that there is a BYTE-based endianness. If BOOST_ENDIAN_LITTLE_WORD_UNIQUE_AVAILABLE is defined, the complement (#else) BOOST_ENDIAN_BIG_WORD_UNIQUE_AVAILABLE is mandatory. If BOOST_ENDIAN_BIG_WORD_UNIQUE_AVAILABLE is defined, the complement (#else) BOOST_ENDIAN_LITTLE_WORD_UNIQUE_AVAILABLE is mandatory.
// unique LITTLE_BYTE
is only defined if the unique endianness is BYTE-based and LITTLE_BYTE
// unique BIG_BYTE
is only defined if the unique endianness is BYTE-based and BIG_BYTE
This can be ruled out that a WORD-based endianness is present. If BOOST_ENDIAN_LITTLE_BYTE_UNIQUE_AVAILABLE is defined, the complement (#else) BOOST_ENDIAN_BIG_BYTE_UNIQUE_AVAILABLE is mandatory. If BOOST_ENDIAN_BIG_BYTE_UNIQUE_AVAILABLE is defined, the complement (#else) BOOST_ENDIAN_LITTLE_BYTE_UNIQUE_AVAILABLE is mandatory.
cu Gero
#if defined(BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE) || defined(BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE)
Why you need to check both? Either you use little or big endian.
Your unique
term does not mean unique actually, it means more like not nested endian
. The unique
here would be a specific combination of byte and word endians.
These lines of code is quite hard to read mess. Why not write directly?
#if BOOST_ENDIAN_BIG_BYTE || BOOST_ENDIAN_LITTLE_BYTE
# define BOOST_ENDIAN_BYTE_UNIQUE_AVAILABLE
# if !BOOST_ENDIAN_BIG_WORD
# if !BOOST_ENDIAN_LITTLE_WORD
# define BOOST_ENDIAN_UNIQUE_AVAILABLE
//...
#endif
#if BOOST_ENDIAN_BIG_WORD || BOOST_ENDIAN_LITTLE_WORD
# define BOOST_ENDIAN_WORD_UNIQUE_AVAILABLE
# if !BOOST_ENDIAN_BIG_BYTE
# if !BOOST_ENDIAN_LITTLE_BYTE
# define BOOST_ENDIAN_UNIQUE_AVAILABLE
//...
#endif
It would be much more readable.
Why you need to check both? Either you use little or big endian.
This is exactly the conclusion. It is NOT guaranteed that in the case
because other combinations can occur
https://en.cppreference.com/w/cpp/types/endian (mixed-end, PDP). With the UNIQUE macros it can be guaranteed that ONLY the complement in the else-branch is used.
thx Gero
It is NOT guaranteed that in the case
It does not guarantee either in your case, because you always need to write the else branch no matter what macro you are using. In both cases you can forget that. So it still is not clear why this need.
Hello, often the mistake is made (happened to me too) to consider only 2 cases when checking the endianess, eg:
struct foo {
if defined(BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE)
uint32_t a : 16; uint32_t b : 16;
else
uint32_t b : 16; uint32_t a : 16;
endif
};
because the else branch is not necessarily BOOST_ENDIAN_BIG_BYTE_AVAILABLE. More correctly, this example must read:
struct foo {
if defined(BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE)
uint32_t a : 16; uint32_t b : 16;
elif defined(BOOST_ENDIAN_BIG_BYTE_AVAILABLE)
uint32_t b : 16; uint32_t a : 16;
else
error or
specializations for BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE/BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE
endif
};
This is error-prone and usually overlooked. Therefore it would make sense to provide unique macros that guarantee that ONLY the contrary endianess is used in the else-branch, eg endian.hpp.txt. Now we can use correctly:
struct foo {
if defined(BOOST_ENDIAN_LITTLE_BYTE_UNIQUE_AVAILABLE)
uint32_t a : 16; uint32_t b : 16;
else
uint32_t b : 16; uint32_t a : 16;
endif
};
But this means that these unique-macros are actually used. It would probably make more sense to "teach" this behavior to the existing macros.
thx & regards Gero