Re: Equivalency of Integral Pointers

Discussion in 'C Programming' started by Ben Bacarisse, Aug 8, 2008.

  1. William Ahern <william@wilbur.25thandClement.com> writes:

    > I'm writing an unpack function which uses "c", "h", "l", "q" format tokens
    > to specify the type of the integral object pointer. To support fixed-width
    > types, a la <stdint.h>, another format specifier, "i", can be prefixed with
    > the width--8, 16, 32, 64, etc. Then, a jump table is used to branch to the
    > native type conversion based on the size of the native type. (This is
    > distinct from specifying the number of input bits to consume in the
    > conversion, and in general disregards the propriety of such fixed-width to
    > native type-punning.)
    >
    > Problem: if we don't match a native type, and we wish to soldier on,
    > discarding input bits and skipping the variable argument without
    > deferencing, does `va_arg(ap, int *)' exhibit well-defined behavior in
    > attempting to consume _any_ integral pointer variable argument?


    I think the only defined way is to require that all the pointer
    parameters be converted to void * in the calling function, then
    var_arg(ap, void *) will skip one pointer arg for sure. The
    conversion to your desired integral type (for those cases where you
    aren't skipping the unpacking) is also guaranteed, of course. The
    conversion in the caller has to be explicit:

    unpack(format, (void *)intp, (void *)longp);

    The trouble is that, while I can't think of an implementation which
    will catch you if you do the undefined va_arg(ap, int *), there are
    those on which forgetting the (void *) will be fatal. Because of
    this, I'd be tempted to wing it.

    BTW, does anyone know why trailing object pointers are not converted
    to void * when calling a function with a (xxx, ...) prototype? It
    seems the logical choice to me.

    --
    Ben.
     
    Ben Bacarisse, Aug 8, 2008
    #1
    1. Advertising

  2. "Malcolm McLean" <> writes:

    > "Ben Bacarisse" <> wrote in message
    >> I think the only defined way is to require that all the pointer
    >> parameters be converted to void * in the calling function,
    >>

    > Which IMO is unacceptable.


    Yes. Maybe you prefer it if I agree with you rather than the other
    way round. I can't think why else you'd snip the part where I say I
    don't like this solution either!

    > I think you need to accept that the code
    > will break if shorts have a different representation to int.


    But here I don't see the connection. All the OP wants to do is to
    skip over an unused va_arg pointer. It is very unlikely that the
    kind of int pointed to will matter.

    > Or better
    > still establish a convention that int is the only integral type in
    > actual use.


    And how many bits should it have? ;-)

    --
    Ben.
     
    Ben Bacarisse, Aug 8, 2008
    #2
    1. Advertising

  3. Ben Bacarisse <> writes:
    [...]
    > BTW, does anyone know why trailing object pointers are not converted
    > to void * when calling a function with a (xxx, ...) prototype? It
    > seems the logical choice to me.


    scanf() and friends need to accept arguments of type int*, long*,
    double*, and so forth.

    I suppose the int* argument could be converted to void*, and then
    scanf could convert it back to int* internally.

    But I think it's mostly just historical practice. printf and scanf
    existed before the ", ..." / <stdarg.h> mechanism was invented, and
    functions that needed to take variable numbers of arguments just
    traversed memory to get at them. The caller was just expected to pass
    the expected type.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Aug 8, 2008
    #3
  4. Keith Thompson <> writes:

    > Ben Bacarisse <> writes:
    > [...]
    >> BTW, does anyone know why trailing object pointers are not converted
    >> to void * when calling a function with a (xxx, ...) prototype? It
    >> seems the logical choice to me.

    >
    > scanf() and friends need to accept arguments of type int*, long*,
    > double*, and so forth.
    >
    > I suppose the int* argument could be converted to void*, and then
    > scanf could convert it back to int* internally.


    That is a small cost to the implementation -- it knows that type
    expected at that point.

    > But I think it's mostly just historical practice. printf and scanf
    > existed before the ", ..." / <stdarg.h> mechanism was invented, and
    > functions that needed to take variable numbers of arguments just
    > traversed memory to get at them. The caller was just expected to pass
    > the expected type.


    I am sure you are right that it is history, but when .../stdarg.h was
    added, would it have broken any programs to make this change? All
    existing code would have involved functions being called without a
    prototype.

    --
    Ben.
     
    Ben Bacarisse, Aug 9, 2008
    #4
  5. Ben Bacarisse <> writes:

    > William Ahern <william@wilbur.25thandClement.com> writes:
    >
    >> I'm writing an unpack function which uses "c", "h", "l", "q" format tokens
    >> to specify the type of the integral object pointer. To support fixed-width
    >> types, a la <stdint.h>, another format specifier, "i", can be prefixed with
    >> the width--8, 16, 32, 64, etc.

    <snip>
    > The trouble is that, while I can't think of an implementation which
    > will catch you if you do the undefined va_arg(ap, int *),


    When I wrote that, I had not spotted the "8". When I saw Keith
    Thompson's reply, I went back and read your post again and saw that
    you are including byte pointers. I might still be inclined to "wing
    it" but there are more machines with wider char * (and void *) than
    there are with different sized pointers to the other integer types.
    They tend to be word-addressed number-crunchers on the whole.

    --
    Ben.
     
    Ben Bacarisse, Aug 9, 2008
    #5
  6. On Fri, 08 Aug 2008 22:06:22 +0100, Ben Bacarisse
    <> wrote:

    >"Malcolm McLean" <> writes:
    >
    >> "Ben Bacarisse" <> wrote in message
    >>> I think the only defined way is to require that all the pointer
    >>> parameters be converted to void * in the calling function,
    >>>

    >> Which IMO is unacceptable.

    >
    >Yes. Maybe you prefer it if I agree with you rather than the other
    >way round. I can't think why else you'd snip the part where I say I
    >don't like this solution either!
    >
    >> I think you need to accept that the code
    >> will break if shorts have a different representation to int.

    >
    >But here I don't see the connection. All the OP wants to do is to
    >skip over an unused va_arg pointer. It is very unlikely that the
    >kind of int pointed to will matter.


    It is not the kind of integer pointed to; it is the size of the
    pointers themselves. If the pointers have different sizes, attempting
    to skip over a short* with code that references an int* will cause the
    wrong number of bytes to be skipped.

    --
    Remove del for email
     
    Barry Schwarz, Aug 9, 2008
    #6
  7. Barry Schwarz <> writes:

    > On Fri, 08 Aug 2008 22:06:22 +0100, Ben Bacarisse
    > <> wrote:
    >
    >>"Malcolm McLean" <> writes:
    >>
    >>> "Ben Bacarisse" <> wrote in message
    >>>> I think the only defined way is to require that all the pointer
    >>>> parameters be converted to void * in the calling function,
    >>>>
    >>> Which IMO is unacceptable.

    >>
    >>Yes. Maybe you prefer it if I agree with you rather than the other
    >>way round. I can't think why else you'd snip the part where I say I
    >>don't like this solution either!
    >>
    >>> I think you need to accept that the code
    >>> will break if shorts have a different representation to int.

    >>
    >>But here I don't see the connection. All the OP wants to do is to
    >>skip over an unused va_arg pointer. It is very unlikely that the
    >>kind of int pointed to will matter.

    >
    > It is not the kind of integer pointed to; it is the size of the
    > pointers themselves. If the pointers have different sizes, attempting
    > to skip over a short* with code that references an int* will cause the
    > wrong number of bytes to be skipped.


    Totally agree. I was claiming (having failed to spot that 8-bit
    integers -- i.e. bytes -- are also being pointed to) that it is
    unlikely that and int * and shot * will be different length. I know
    this is possible, but the most common pointer size differences are
    between char */void * and all other objects pointers (function
    pointers not being at issue here). I could not see why Malcolm was
    introducing the differences between the representations of the ints
    themselves when, as you say, it is the pointer sizes that matter.

    Of course, this is all about what happens in practise. On paper, just
    accessing va_arg(ap, int *) when the corresponding parameter is a long
    * is UB not matter what the pointer sizes and representations.

    --
    Ben.
     
    Ben Bacarisse, Aug 9, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stacy Mader
    Replies:
    4
    Views:
    879
    Ekkehard Morgenstern
    Nov 22, 2003
  2. Grant Austin
    Replies:
    3
    Views:
    459
    Peter van Merkerk
    Dec 9, 2003
  3. Barry Schwarz

    Re: Equivalency of Integral Pointers

    Barry Schwarz, Aug 8, 2008, in forum: C Programming
    Replies:
    9
    Views:
    315
  4. Brad Tilley

    string equivalency

    Brad Tilley, Aug 16, 2006, in forum: Ruby
    Replies:
    3
    Views:
    108
    Robert Klemme
    Aug 16, 2006
  5. tom.mancino

    Functional Equivalency

    tom.mancino, Oct 25, 2006, in forum: Ruby
    Replies:
    7
    Views:
    166
    Rick DeNatale
    Oct 26, 2006
Loading...

Share This Page