Boost logo

Boost :

From: Jeffrey C. Jacobs (darklord_at_[hidden])
Date: 2002-09-25 16:27:13


Thanks for the info Greg,

I have now read the section of the C99 standard to which you refer
(5.2.4.2.1) in its entirity and it is very intesting -- did you know I call
myself a language lawyer in training; not a good idea to quote standards at
me because you might be surprised what I get when I parse it. :) But
seriously, if C++ (currently predating C99) follows the same suit, which is
quite feasable, I admit there is ONE mis-statement I made, though not the
one to which you refer.

Simply, C99 5.2.4.2.1 [1], the section you quoted, states that the values
listed are a MINIMUM required size for intrinsic types. Specifically, it
states "Their implementation-defined values shall be equal or greater in
magnitude (absolute value) to those shown, with the same sign." which I take
to mean, if I as an implementor choose to make ULONG_MAX ==
18446744073709551615 (ULLONG_MAX in the standard) I would still be
conformant to the ISO C99 standard. In fact, if I chose to set ULONG_MAX ==
2**128-1 I would STILL be conformant to ISO C99. I could even keep
ULLONG_MAX at 2**64-1 meaning long was bigger than long long, though I think
any implementor who tried that would have a lot of trouble selling even one
copy of hir compiler! :)

Now, since C99 says that char must be 8 bits (unlike AFAICT from "The C++
Programming Language", which implies that 8-bits is a MINIMUM but NOT
required) and assuming sizeof(char) is 1, C99 5.2.4.2.1 [1] states
essentially that:

sizeof(short) >= 2
sizeof(int) >= 2
sizeof(long) >= 4
sizeof(long long) >= 8

Clearly if you DO take those numbers literally you'd have to include that
"int" must always be 16-bits! The standard wants to leave some flexibility
to the compiler since most C these days is on 32-bit platforms and therefore
sizeof(int) == 4, not 2.

However, it is IMPOSSIBLE in ISO conformant C99 to have:

1, 1, 1, 1, 1 {char, short, int, long, long long }

which I stated incorectly before. I think this is still possible in ISO C++
(have to read the standard again) but I accept that a) no implementation is
likely to take that approach, therefore it is safe IMHO to ignore b) it does
I agree NOT conform to C99 and by implication likely will not conform with
C++03 or whatever and c) it is not needed in my argument against associating
long long and __int64 directly.

Even in C99, one can have a long long of greater than 64 bits; in fact 128
bits would be quite reasonable on a DEC Alpha. Equally, as on Compac's DEC
Alpha compiler (as stated elsewhere) long can be MORE than the C99-minimum
32-bits. (It has 64.) It's not hard then to imagine that some compiler
could be developed where ints (and thus the native archetecture) are 64
bits, longs are 128 bits and long longs are 256 bits. It would certainly
not be beyond C99 to implement it that way. And if you did, then
int_least_helper would not work with __int64:

1 __int64 64 bits
2 long 128 bits
3 int 64 bits
4 short 32 bits
5 char 8 bits
7, 8, 9, 10, 11 same with unsigned forms

The MPL to generate int_t<128>::fast would then be __int64!! since you add 1
for the long, none for the others and the helper at 1 is __int64! Because
__int64 is fixed and long long is not (neither is long) I still say it is
NOT safe to assume long long is equivalent to __int64.

Anyway, thanks Greg for the VERY interesting discussion.

Jeffrey.

"Greg Colvin" <Gregory.Colvin_at_[hidden]> wrote in message
news:5.1.1.6.2.20020925135000.02b7c828_at_rgmgitmail.oraclecorp.com...
At 01:30 PM 9/25/2002, Jeffrey C. Jacobs wrote:
>Oops! My bad!
>
>Actually, the MSVC++ compiler considers __int<x> as separate types from
int,
>long, etc. (having checked the name mangling -- what a mess they make of
>specializations with these MS-types!!). Let me consider the issue further
>and get back to y'all but my belief remains that we should not assume
>__int64 == long long, specifically when my theory is "long long" will not
be
>standardized at 64 bits, simply bigger or as big as long.

Unless C++ fails to follow C99 your theory is wrong:

5.2.4.2.1 Sizes of integer types <limits.h>

The values given below shall be replaced by
constant expressions suitable for use in #if
preprocessing directives. Moreover, except for
CHAR_BIT and MB_LEN_MAX, the following shall be
replaced by expressions that have the same type
as would an expression that is an object of the
corresponding type converted according to the
integer promotions. Their implementation-defined
values shall be equal or greater in magnitude
(absolute value) to those shown, with the same
sign.

..

- minimum value for an object of type long long int
LLONG_MIN -9223372036854775807 // -(2**63 - 1)

- maximum value for an object of type long long int
LLONG_MAX +9223372036854775807 // 2**63 - 1

- maximum value for an object of type unsigned long long int
ULLONG_MAX 18446744073709551615 // 26**4 - 1


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk