This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH v2] Add <sys/_stdint.h> for FreeBSD compatibility


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__ */




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]