Paul Eggert wrote: > * doc/posix-headers/limits.texi (limits.h): Document this. > * lib/limits.in.h (SSIZE_MAX): Define if not already defined.
When I add a unit test for this, I see that the assertion static_assert (TYPE_MAXIMUM (ssize_t) == SSIZE_MAX); fails on 64-bit MSVC 14. That's because on this platform, gnulib defines ssize_t as 'int', i.e. 32-bit, whereas size_t is 64-bit. Ouch. And when we used # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) that value actually was (int)(-1). Ouch ouch. 2023-05-21 Bruno Haible <br...@clisp.org> limits-h tests: Check the value of SSIZE_MAX. * tests/test-limits-h.c (limits12): New variable. Include <sys/types.h> and check the value of SSIZE_MAX. * modules/limits-h-tests (Depends-on): Add sys_types. 2023-05-21 Bruno Haible <br...@clisp.org> ssize_t: Fix replacement on 64-bit Windows. * m4/ssize_t.m4 (gt_TYPE_SSIZE_T): Use prefix 'gl_' instead of 'gt_'. Define ssize_t to 'long long' or 'long', depending on the width of 'size_t'.
>From 138b4121298c14e1fd6ca751ab557a1d65443f01 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 21 May 2023 14:40:04 +0200 Subject: [PATCH 1/2] ssize_t: Fix replacement on 64-bit Windows. * m4/ssize_t.m4 (gt_TYPE_SSIZE_T): Use prefix 'gl_' instead of 'gt_'. Define ssize_t to 'long long' or 'long', depending on the width of 'size_t'. --- ChangeLog | 7 +++++++ m4/ssize_t.m4 | 28 +++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7253bd7ea3..e205c02f43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-05-21 Bruno Haible <br...@clisp.org> + + ssize_t: Fix replacement on 64-bit Windows. + * m4/ssize_t.m4 (gt_TYPE_SSIZE_T): Use prefix 'gl_' instead of 'gt_'. + Define ssize_t to 'long long' or 'long', depending on the width of + 'size_t'. + 2023-05-20 Paul Eggert <egg...@cs.ucla.edu> limits-h: other modules can rely on SSIZE_MAX diff --git a/m4/ssize_t.m4 b/m4/ssize_t.m4 index 1c12c33ea0..52bd77d2ae 100644 --- a/m4/ssize_t.m4 +++ b/m4/ssize_t.m4 @@ -1,23 +1,37 @@ -# ssize_t.m4 serial 5 (gettext-0.18.2) +# ssize_t.m4 serial 6 dnl Copyright (C) 2001-2003, 2006, 2010-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. -dnl Test whether ssize_t is defined. +dnl Define ssize_t if it does not already exist. AC_DEFUN([gt_TYPE_SSIZE_T], [ - AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t], + AC_CACHE_CHECK([for ssize_t], [gl_cv_ssize_t], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include <sys/types.h>]], [[int x = sizeof (ssize_t *) + sizeof (ssize_t); return !x;]])], - [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])]) - if test $gt_cv_ssize_t = no; then - AC_DEFINE([ssize_t], [int], - [Define as a signed type of the same size as size_t.]) + [gl_cv_ssize_t=yes], [gl_cv_ssize_t=no])]) + if test $gl_cv_ssize_t = no; then + dnl On 64-bit native Windows, ssize_t needs to be defined as 'long long', + dnl for consistency with the 64-bit size_t. + AC_CACHE_CHECK([whether size_t is wider than 'long'], [gl_cv_size_t_large], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <sys/types.h> + typedef int array [2 * (sizeof (size_t) > sizeof (long)) - 1]; + ]])], + [gl_cv_size_t_large=yes], [gl_cv_size_t_large=no])]) + if test $gl_cv_size_t_large = yes; then + gl_def_ssize_t='long long' + else + gl_def_ssize_t='long' + fi + AC_DEFINE_UNQUOTED([ssize_t], [$gl_def_ssize_t], + [Define as a signed type of the same size as size_t.]) fi ]) -- 2.34.1
>From a5865b6ed2fe6810ec1f557e79794ce525fcb935 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sun, 21 May 2023 14:42:27 +0200 Subject: [PATCH 2/2] limits-h tests: Check the value of SSIZE_MAX. * tests/test-limits-h.c (limits12): New variable. Include <sys/types.h> and check the value of SSIZE_MAX. * modules/limits-h-tests (Depends-on): Add sys_types. --- ChangeLog | 7 +++++++ modules/limits-h-tests | 1 + tests/test-limits-h.c | 11 +++++++++++ 3 files changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index e205c02f43..9cdb603b9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2023-05-21 Bruno Haible <br...@clisp.org> + + limits-h tests: Check the value of SSIZE_MAX. + * tests/test-limits-h.c (limits12): New variable. + Include <sys/types.h> and check the value of SSIZE_MAX. + * modules/limits-h-tests (Depends-on): Add sys_types. + 2023-05-21 Bruno Haible <br...@clisp.org> ssize_t: Fix replacement on 64-bit Windows. diff --git a/modules/limits-h-tests b/modules/limits-h-tests index 2cf0a41f5d..51919ad1a1 100644 --- a/modules/limits-h-tests +++ b/modules/limits-h-tests @@ -4,6 +4,7 @@ tests/test-limits-h.c Depends-on: assert-h extensions +sys_types limits-h-c++-tests configure.ac: diff --git a/tests/test-limits-h.c b/tests/test-limits-h.c index d7cfba7131..253d2362e7 100644 --- a/tests/test-limits-h.c +++ b/tests/test-limits-h.c @@ -94,6 +94,10 @@ unsigned long long limits11[] = { ULLONG_MAX }; static_assert (TYPE_MINIMUM (unsigned long long int) == 0); static_assert (TYPE_MAXIMUM (unsigned long long int) == ULLONG_MAX); +/* Specified by POSIX, not by ISO C. */ + +long long limits12[] = { SSIZE_MAX }; + /* Macros specified by C23 and by ISO/IEC TS 18661-1:2014. */ verify_width (CHAR_WIDTH, CHAR_MIN, CHAR_MAX); @@ -115,6 +119,13 @@ static_assert (BOOL_MAX == (((1U << (BOOL_WIDTH - 1)) - 1) * 2) + 1); static_assert (0 < MB_LEN_MAX); +/* Get ssize_t, size_t. */ +#include <sys/types.h> + +static_assert (TYPE_MAXIMUM (ssize_t) == SSIZE_MAX); +/* Verify that ssize_t has the same width as size_t. */ +static_assert (TYPE_MAXIMUM (size_t) / 2 == SSIZE_MAX); + int main (void) { -- 2.34.1