[PATCH v2] Add <sys/_stdint.h> for FreeBSD compatibility
Craig Howland
howland@LGSInnovations.com
Wed Apr 29 11:08:00 GMT 2015
On 04/28/2015 07:09 AM, Corinna Vinschen wrote:
> On Apr 28 12:41, Corinna Vinschen wrote:
>> On Apr 1 20:42, Corinna Vinschen wrote:
>>> On Apr 1 14:28, Corinna Vinschen wrote:
>>>> On Apr 1 10:12, Corinna Vinschen wrote:
>>>>> On Apr 1 09:58, Sebastian Huber wrote:
>>>>>> v2: Move also intptr_t and uintptr_t.
>>>>> Thanks. I still didn't manage to complete my testcase but I *am*
>>>>> working on it :}
>>>> Ok, I managed to do my test. The patch looks good. However, there's
>>>> one point I'd like to discuss.
>>>>
>>>> The Cygwin stdint.h defines all the MIN/MAX values with enclosing
>>>> parens, just like GLibc's stdint.h does. Shan't we do the same in
>>>> newlib's stdint.h? It might not really necessary, technically, but
>>>> it looks cleaner somehow.
>>> Patch applied. I added the parens in a followup patch.
>> Oh well. I managed to miss a problem during testing. We just got a
>> report on the Cygwin mailing list.
>>
>> The 32 bit types (e.g. int32_t, uint least32_t) on 32 bit i686 Cygwin,
>> are defined as "int". However, the tests in sys/_intsup.h lead to the
>> definition of __have_long32 to 1, which in turn results in using long
>> constants in stdint.h and inttypes.h for 32 bit macros. And this in
>> turn results in GCC warnings:
>>
>> printf("int = %"PRId32", uint = %"PRIu32".\n", ival, uval);
>> ^
>> x.c:9:9: warning: format â%luâ expects argument of type âlong unsigned intâ,
>> but argument 3 has type âuint32_tâ [-Wformat=]
>> x.c:9:9: warning: format â%ldâ expects argument of type âlong intâ, but
>> argument 2 has type âint32_tâ [-Wformat=]
>>
>> On second thought, the definition of __have_long32 in sys/_intsup.h
>> always prefers "long" over "int", no matter how GCC actually defines the
>> base types __uint32_t, etc.
> In other words, just because a target has a 32 bit long doesn't mean
> the base type for int32_t is long.
>
>> So the question is, shouldn't we use the same new method we're using
>> to find the right definition for {u}intptr_t for the {u}int32_t types
>> as well?
> Below is my proposal.
>
> It moves the _UINTPTR_EQ_ULONG stuff from sys/config.h to sys/_intsup.h
> and renames it slightly to refer to the signed base type ("drop the
> "U"s). Then it adds a test to set _INT32_EQ_LONG using the same
> technique.
>
> stdint.h and inttypes.h replace the test for __have_long32 with a test
> for `ifdef _INT32_EQ_LONG'.
>
> Does that look ok?
A small suggestion: rather than _INT32_EQ_LONG (int32 equals long), how
about _INT32_IS_LONG or _INT32_TYPEIS_LONG, etc.? They can be equal without
being the same type, so the "equals" diction does not tell you by the name alone
what is meant. (This case is not the same as _LDBL_EQ_DBL, the intent of which
is to tell that the encoding is the same for the two different types.) The same
would apply to _INTPTR_EQ_LONG.
The grand plan looks OK.
>
>
> Thanks,
> Corinna
>
> * libc/include/sys/config.h: Move evaluation of _UINTPTR_EQ_ULONG
> and _UINTPTR_EQ_ULONGLONG from here...
> * libc/include/sys/_intsup.h: ...to here. Rename to _INTPTR_EQ_LONG
> and _INTPTR_EQ_LONGLONG to refer to signed base type. Add test
> for base type of int32_t and set _INT32_EQ_LONG accordingly.
> * libc/include/stdint.h: Change checks for __have_long32 to checks
> for _INT32_EQ_LONG.
> * libc/include/inttypes.h: Ditto. Accommodate aforementioned name
> change.
>
> diff --git a/newlib/libc/include/inttypes.h b/newlib/libc/include/inttypes.h
> index 52b2d84..7158cc6 100644
> --- a/newlib/libc/include/inttypes.h
> +++ b/newlib/libc/include/inttypes.h
> @@ -142,7 +142,7 @@
> #define SCNxFAST16 __SCN16(x)
>
> /* 32-bit types */
> -#if __have_long32
> +#if defined (_INT32_EQ_LONG)
> #define __PRI32(x) __STRINGIFY(l##x)
> #define __SCN32(x) __STRINGIFY(l##x)
> #else
> @@ -272,10 +272,10 @@
> #define SCNxMAX __SCNMAX(x)
>
> /* ptr types */
> -#if defined(_UINTPTR_EQ_ULONGLONG)
> +#if defined (_INTPTR_EQ_LONGLONG)
> # define __PRIPTR(x) __STRINGIFY(ll##x)
> # define __SCNPTR(x) __STRINGIFY(ll##x)
> -#elif defined(_UINTPTR_EQ_ULONG)
> +#elif defined (_INTPTR_EQ_LONG)
> # define __PRIPTR(x) __STRINGIFY(l##x)
> # define __SCNPTR(x) __STRINGIFY(l##x)
> #else
> diff --git a/newlib/libc/include/stdint.h b/newlib/libc/include/stdint.h
> index aa9d68e..bd65cd0 100644
> --- a/newlib/libc/include/stdint.h
> +++ b/newlib/libc/include/stdint.h
> @@ -216,7 +216,7 @@ typedef __uint_least64_t uint_least64_t;
> #define INT32_MAX (__INT32_MAX__)
> #define UINT32_MAX (__UINT32_MAX__)
> #elif defined(__int32_t_defined)
> -#if __have_long32
> +#if defined (_INT32_EQ_LONG)
> #define INT32_MIN (-2147483647L-1)
> #define INT32_MAX (2147483647L)
> #define UINT32_MAX (4294967295UL)
> @@ -232,7 +232,7 @@ typedef __uint_least64_t uint_least64_t;
> #define INT_LEAST32_MAX (__INT_LEAST32_MAX__)
> #define UINT_LEAST32_MAX (__UINT_LEAST32_MAX__)
> #elif defined(__int_least32_t_defined)
> -#if __have_long32
> +#if defined (_INT32_EQ_LONG)
> #define INT_LEAST32_MIN (-2147483647L-1)
> #define INT_LEAST32_MAX (2147483647L)
> #define UINT_LEAST32_MAX (4294967295UL)
> @@ -439,7 +439,7 @@ typedef __uint_least64_t uint_least64_t;
> #define INT32_C(x) __INT32_C(x)
> #define UINT32_C(x) __UINT32_C(x)
> #else
> -#if __have_long32
> +#if defined (_INT32_EQ_LONG)
> #define INT32_C(x) x##L
> #define UINT32_C(x) x##UL
> #else
> diff --git a/newlib/libc/include/sys/_intsup.h b/newlib/libc/include/sys/_intsup.h
> index 7c3bc01..6c53641 100644
> --- a/newlib/libc/include/sys/_intsup.h
> +++ b/newlib/libc/include/sys/_intsup.h
> @@ -33,4 +33,39 @@
> #define __have_long32 1
> #endif
>
> +/* Determine how intptr_t and int32_t are defined by gcc for this target. This
> + is used to determine the correct printf() constant in inttypes.h and other
> + constants in stdint.h. */
> +#pragma push_macro("signed")
> +#pragma push_macro("int")
> +#pragma push_macro("long")
> +#undef signed
> +#undef int
> +#undef long
> +#define signed +0
> +#define int +0
> +#define long +1
> +#if __INTPTR_TYPE__ == 2
> +#define _INTPTR_EQ_LONGLONG
> +#elif __INTPTR_TYPE__ == 1
> +#define _INTPTR_EQ_LONG
> +#elif __INTPTR_TYPE__ == 0
> +/* Nothing to define because intptr_t is safe to print as an int. */
> +#else
> +#error "Unable to determine type definition of intptr_t"
> +#endif
> +#if __INT32_TYPE__ == 1
> +#define _INT32_EQ_LONG
> +#elif __INT32_TYPE__ == 0
> +/* Nothing to define because int32_t is safe to print as an int. */
> +#else
> +#error "Unable to determine type definition of int32_t"
> +#endif
> +#undef long
> +#undef int
> +#undef signed
> +#pragma pop_macro("signed")
> +#pragma pop_macro("int")
> +#pragma pop_macro("long")
> +
> #endif /* _SYS__INTSUP_H */
> diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
> index 04f1e3a..5297bef 100644
> --- a/newlib/libc/include/sys/config.h
> +++ b/newlib/libc/include/sys/config.h
> @@ -287,30 +287,4 @@
> #define _MB_EXTENDED_CHARSETS_WINDOWS 1
> #endif
>
> -/* Determine how uintptr_t is defined by gcc for this target. This
> - is used to determine the correct printf() constant in inttypes.h */
> -#pragma push_macro("signed")
> -#pragma push_macro("int")
> -#pragma push_macro("long")
> -#undef signed
> -#undef int
> -#undef long
> -#define signed +0
> -#define int +0
> -#define long +1
> -#if __INTPTR_TYPE__ == 2
> -#define _UINTPTR_EQ_ULONGLONG
> -#elif __INTPTR_TYPE__ == 1
> -#define _UINTPTR_EQ_ULONG
> -#elif __INTPTR_TYPE__ == 0
> -/* Nothing to define because intptr_t is safe to print as an int. */
> -#else
> -#error "Unable to determine type definition of uintptr_t"
> -#endif
> -#undef long
> -#undef int
> -#undef signed
> -#pragma pop_macro("signed")
> -#pragma pop_macro("int")
> -#pragma pop_macro("long")
> #endif /* __SYS_CONFIG_H__ */
>
>
More information about the Newlib
mailing list