[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Fix size_max macro
From: |
Bruno Haible |
Subject: |
Fix size_max macro |
Date: |
Tue, 13 Jun 2006 18:10:06 +0200 |
User-agent: |
KMail/1.9.1 |
Hi,
The size_max macro has a bug: it assumes that 'expr' can deal with numbers as
large as SIZE_MAX/10. Which is not true when cross-compiling from a 32-bit
platform to a 64-bit platform.
Here is a fix, that takes care that SIZE_MAX is valid in preprocessor
expressions (i.e. contains no casts).
OK to commit?
Bruno
*** m4/size_max.m4 11 Jul 2005 11:29:40 -0000 1.4
--- m4/size_max.m4 13 Jun 2006 15:44:30 -0000
***************
*** 1,5 ****
! # size_max.m4 serial 3
! dnl Copyright (C) 2003, 2005 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.
--- 1,5 ----
! # size_max.m4 serial 4
! dnl Copyright (C) 2003, 2005-2006 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.
***************
*** 24,50 ****
if test -z "$result"; then
dnl Define it ourselves. Here we assume that the type 'size_t' is not
wider
dnl than the type 'unsigned long'.
! dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr',
! dnl which is guaranteed to work from LONG_MIN to LONG_MAX.
! _AC_COMPUTE_INT([(size_t)~(size_t)0 / 10], res_hi,
! [#include <stddef.h>], result=?)
! _AC_COMPUTE_INT([(size_t)~(size_t)0 % 10], res_lo,
! [#include <stddef.h>], result=?)
_AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint,
! [#include <stddef.h>], result=?)
! if test "$fits_in_uint" = 1; then
! dnl Even though SIZE_MAX fits in an unsigned int, it must be of type
! dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'.
! AC_TRY_COMPILE([#include <stddef.h>
! extern size_t foo;
! extern unsigned long foo;
! ], [], fits_in_uint=0)
! fi
! if test -z "$result"; then
! if test "$fits_in_uint" = 1; then
! result="$res_hi$res_lo"U
else
! result="$res_hi$res_lo"UL
fi
else
dnl Shouldn't happen, but who knows...
--- 24,50 ----
if test -z "$result"; then
dnl Define it ourselves. Here we assume that the type 'size_t' is not
wider
dnl than the type 'unsigned long'.
! _AC_COMPUTE_INT([sizeof (size_t) * CHAR_BIT - 2], size_t_bits_minus_2,
! [#include <stddef.h>
! #include <limits.h>], size_t_bits_minus_2=)
_AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint,
! [#include <stddef.h>], fits_in_uint=)
! if test -n "$size_t_bits_minus_2" && test -n "$fits_in_uint"; then
! if test $fits_in_uint = 1; then
! dnl Even though SIZE_MAX fits in an unsigned int, it must be of type
! dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned
long'.
! AC_TRY_COMPILE([#include <stddef.h>
! extern size_t foo;
! extern unsigned long foo;
! ], [], fits_in_uint=0)
! fi
! dnl We cannot use 'expr' to simplify this expression, because 'expr'
! dnl works only with 'long' integers in the host environment, while we
! dnl might be cross-compiling from a 32-bit platform to a 64-bit
platform.
! if test $fits_in_uint = 1; then
! result="(((1U << $size_t_bits_minus_2) - 1) * 2 + 1)"
else
! result="(((1UL << $size_t_bits_minus_2) - 1) * 2 + 1)"
fi
else
dnl Shouldn't happen, but who knows...
- Fix size_max macro,
Bruno Haible <=