Hi Paul,
While I understand the purpose of namespace cleanliness — so that the
compiler can tell the programmer that a '#include <stdint.h>' (in this case)
is missing —, I think of it as a secondary goal that we rarely can achieve,
and the introduced complexity is starting to be greater than the benefit.
Also:
> +# define _GL_STDBIT_UINT_FAST16 __UINT_FAST16_TYPE__
> +# define _GL_STDBIT_UINT_FAST32 __UINT_FAST32_TYPE__
> +# define _GL_STDBIT_UINT_FAST64 __UINT_FAST64_TYPE__
The GCC documentation [1] says about these macros:
"You should not use these macros directly; instead, include the
appropriate headers and use the typedefs."
> _GL_STDC_LOAD8_INLINE uint_least16_t
> stdc_load8_beu16 (const unsigned char ptr[2])
> {
> - return ((uint_fast16_t) ptr[0] << 8) | (uint_fast16_t) ptr[1];
> + _GL_STDBIT_UINT_FAST16 zero = 0;
> + return (((ptr[0] | zero) << (8 * 1))
> + | ((ptr[1] | zero) << (8 * 0)));
> }
Oh please, no! Code should reflect the intent of the programmer. If the
intent is to convert a value of type 'unsigned char' to an 'uint_fast16_t',
a cast is the perfect, understandable way of doing so. Writing it as an
' | zero' is intentional obfuscation.
What was your rationale for avoiding casts in the first place? Does it apply
here, in the situation of converting an integer to another integer type?
Bruno
[1] https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html