Clive D.W. Feather clive at
Wed Aug 4 17:10:11 UTC 2004

Paul Eggert said:
>> Can you give me an example?
> Sure.  Here's an example taken from the code I happened to be looking
> at 30 seconds before reading your email.  It's taken from GNU
> coreutils "od.c".

I've just looked at the actual code. This seems to be doing something a bit
odd - trying to use printf on various types to output integers of
run-time-specified size (if I'm wrong, please say so). My inclination is to
say "don't do that".

> I've paraphrased the code slightly to simplify it.
>   enum size_spec { NO_SIZE, CHAR, SHORT, INT, LONG } ;
>   enum size_spec integral_type_size[sizeof (long) + 1];

I note the actual code has MAX_INTEGRAL_TYPE_SIZE here. This can be
adjusted if necessary.

> This code has undefined behavior if, for example, sizeof (long) is 4
> and sizeof (int) is 8.

This can be tested at compile time: add to "struct dummy" a number of
fields of the form:

    int assert_size_spec_big_enough_for_char
        [MAX_INTEGRAL_TYPE_SIZE + 1 - sizeof (char)];
    int assert_size_spec_big_enough_for_short
        [MAX_INTEGRAL_TYPE_SIZE + 1 - sizeof (short)];
    int assert_size_spec_big_enough_for_int
        [MAX_INTEGRAL_TYPE_SIZE + 1 - sizeof (int)];

> The code in difftime.c is a bit more subtle than this, and now that I
> look at it more carefully it can't strictly be justified in terms of
> either C89 or C99 (though it is true on all platforms I know about).
> However, I'd say that the general principle that sizeof(int) <=
> sizeof(long) is hardwired into a lot of real-world code.

I'm still dubious about "a lot". What's difftime.c doing that needs that

Note that the related assumption INT_MAX <= LONG_MAX *is* guaranteed in
both C89 and C99. UINT_MAX <= ULONG_MAX is guaranteed in C99 but not C89.
[see below]

> If there aren't any real implementations with sizeof(long) <
> sizeof(int), then this is only of academic interest.  Still, it's
> strange that this longstanding requirement would get removed from the
> standard.  After all, it's a natural assumption.

We didn't feel so.

"long can hold any value that int can" is an important property.
"long takes up more space in core than int does" is less obviously so.


C89 said:

    There are four signed integer types, designated as
    signed char, short int, int, and long int. 
    In the list of signed integer types above, the range of values of
    each type is a subrange of the values of the next type in the list.
    The range of nonnegative values of a signed integer type is a
    subrange of the corresponding unsigned integer type,



but you can't derive UINT_MAX <= ULONG_MAX from that.

Clive D.W. Feather  | Work:  <clive at>   | Tel:    +44 20 8495 6138
Internet Expert     | Home:  <clive at>  | Fax:    +44 870 051 9937
Demon Internet      | WWW: | Mobile: +44 7973 377646
Thus plc            |                            |

More information about the tz mailing list