Re: Learning C with Older books ?.

From: Lawrence Kirby (lknews_at_netactive.co.uk)
Date: 12/16/04

  • Next message: Lawrence Kirby: "Re: PROS/CONS: #define BEGIN {"
    Date: Thu, 16 Dec 2004 14:05:21 +0000
    
    

    On Thu, 16 Dec 2004 13:36:22 +0100, Charlie Gordon wrote:

    > "Lawrence Kirby" <lknews@netactive.co.uk> wrote in message
    > news:pan.2004.12.15.11.58.05.484000@netactive.co.uk...
    >> On Tue, 14 Dec 2004 21:06:09 +0100, Charlie Gordon wrote:
    >> > It is really a shame that a cast to the signed version of size_t cannot
    >> > be done portably, and that ssize_t is not part of C99 (but it is part of
    >> > POSIX).
    >>
    >> For all intents and purposes it can be done.
    >
    > How can it be done ?

    As I suggested previously in the article you responded to.

    > C99 doesn't tell us much about the size of size_t, so how can you convert a
    > size_t expression to its signed equivalent, assuming no overflow, and without
    > extending precision ?

    It doesn't have to be the signed equivalent, a type at least as wide as
    that will do just as well, if not better if it can represent all size_t
    values. So the widest integer type supported by the implementation works.
    I do accept that when a wider than necessary type is used in a complex
    expression that type will tend to propagate through the expression, a form
    of "poisoning".

    If you felt it necessary you could in C99 use the preprocessor to find the
    largest signed integer type whose positive range does not exceed that of
    size_t.

    Alternatively you can cast to a type such as int. That would be used where
    other parts of the code (e.g. index variables) require that the size
    be representable as an int so the code would break anyway if it isn't. You
    are no better off using a "true" ssize_t in that respect because even that
    isn't guaranteed to be able to represent all possible object sizes. C
    allows the range of an unsigned integer type to be significantly larger
    than the positive range of the corresponding signed type (not just approx.
    double the size), so IMO ssize_t isn't a particularly useful concept.

    > (intmax_t)sizeof(e) in unacceptable because it potentially
    > extends the size and changes the semantics of the surrounding expression
    > as in
    >
    > sizeof(sizeof(e)) != sizeof((intmax_t)sizeof(e))

    When is this likely to be a problem in real code? If you want
    sizeof(size_t) then write that, or ssizeof(size_t) or intsizeof(size_t) or
    whatever.

    > I advocate casting to (signed) as a lone adjective should do this, but
    > it is incompatible with current C99 semantics that specify (signed) to
    > be quivalent to (signed int).
    >
    > What is your version ?

    Cast to the type of the signed variable or quantity the result will be
    used with, probably. If your problem is selecting a suitable type for that
    then you have to resort to the alternatives above.

    There is no universally perfect solution to this, and that includes a
    "true" ssize_t type. I'm happy to use size_t for my index variables and
    deal with/avoid the fairly clear cut issues that arise from that. If you
    have to count backwards (which is the minority of cases) you can use code
    like

        for (size_t i = (sizeof x)-1; i != (size_t)-1; i--)

    or

        size_t i = sizeof x;
        while (i-- != 0)

    or

        for (size_t i = sizeof x; i != 0; ) {
            i--;
            ...
        }

    Incidentally, this last approach also works naturally with pointers.

    Lawrence


  • Next message: Lawrence Kirby: "Re: PROS/CONS: #define BEGIN {"

    Relevant Pages

    • Re: Learning C with Older books ?.
      ... So the widest integer type supported by the implementation works. ... Alternatively you can cast to a type such as int. ... other parts of the code (e.g. index variables) require that the size ... than the positive range of the corresponding signed type (not just approx. ...
      (alt.comp.lang.learn.c-cpp)
    • Re: Bit-fields and integral promotion
      ... >> The standard very clearly intends to specify the behaviour. ... > whether declared as int or unsigned int, ... "A bit-field is interpreted as a signed or unsigned integer type ... any signed integer type with less precision." ...
      (comp.lang.c)
    • Re: Moving from C++ to VC++
      ... If it is the longest integer. ... have been bad to constrain fseek to 16 bit int offsets, so they used long, ... 8192 bit integer type is a very special type that is mind-boggling overkill ... Storing pointers in an integer is common enough that the C++ Standard ...
      (microsoft.public.vc.language)
    • Re: Implicit int
      ... a wider standard type due size of data objects.to the ever-increasing ... If a 64 bit integer type is desired we can have as int64_t as exact ... in this case where we don't have long long int. ... C99 has two parallel sets of integer types. ...
      (comp.std.c)
    • Re: Max value of a variable
      ... compiler also assigns 32 bits to long long int type of AEIt type, ... integer type; it can be 16, 32, or 64 bits, among other possibilities. ... Note that *all* conforming C99 implementations must support at least ...
      (comp.lang.c)