Why do a cast type structure to an array in this case? - Unix

This is a discussion on Why do a cast type structure to an array in this case? - Unix ; Code: #define BUFSIZE 1500 char sendbuf[BUFSIZE]; void send_v4(void) { int len; stuct icmp *icmp; icmp = (struct icmp *) sendbuf; icmp->icmptype = ICMP_ECHO; icmp->icmpcode = 0; /*rest of code*/ } The question is why force a cast to the array ...

+ Reply to Thread
Results 1 to 10 of 10

Thread: Why do a cast type structure to an array in this case?

  1. Why do a cast type structure to an array in this case?


    Code:

    #define BUFSIZE 1500

    char sendbuf[BUFSIZE];

    void send_v4(void)
    {
    int len;
    stuct icmp *icmp;

    icmp = (struct icmp *) sendbuf;
    icmp->icmptype = ICMP_ECHO;
    icmp->icmpcode = 0;

    /*rest of code*/
    }


    The question is why force a cast to the array sendbuf? Ie why not do
    something like
    Code:

    void send_v4(void)
    {
    int len;
    stuct icmp *icmp;

    icmp->icmptype = ICMP_ECHO;
    icmp->icmpcode = 0;

    /*rest of code*/
    }

    I'm just sort of curious because this type of coding move appears in
    ping and a lot of unix network printer code.


  2. Re: Why do a cast type structure to an array in this case?

    In article <1194576604.969235.278640@y27g2000pre.googlegroups. com>,
    K-mart Cashier wrote:

    > Code:
    >
    > #define BUFSIZE 1500
    >
    > char sendbuf[BUFSIZE];
    >
    > void send_v4(void)
    > {
    > int len;
    > stuct icmp *icmp;
    >
    > icmp = (struct icmp *) sendbuf;
    > icmp->icmptype = ICMP_ECHO;
    > icmp->icmpcode = 0;
    >
    > /*rest of code*/
    > }
    >
    >
    > The question is why force a cast to the array sendbuf? Ie why not do
    > something like
    > Code:
    >
    > void send_v4(void)
    > {
    > int len;
    > stuct icmp *icmp;
    >
    > icmp->icmptype = ICMP_ECHO;
    > icmp->icmpcode = 0;
    >
    > /*rest of code*/
    > }
    >
    > I'm just sort of curious because this type of coding move appears in
    > ping and a lot of unix network printer code.


    In your version the icmp variable is uninitialized. You can't use it
    until it points to some valid memory. That's what sendbuf[] is in the
    original version.

    You could add the following to your version:

    icmp = malloc(BUFSIZE);
    /* rest of code */
    free(icmp);

    The difference is that this would require use of malloc() and free()
    every time your function is called, which can be pretty expensive if
    it's called often. If the function is not used in multiple threads,
    it's more efficient to reuse the same sendbuf[] every time.

    Perhaps what you mean to ask was why you don't write:

    void send_v4(void)
    {
    int len;
    struct icmp icmp;

    icmp.icmptype = ICMP_ECHO;
    icmp.icmpcode = 0;

    /* rest of code */
    }

    The reason is that struct icmp only defines the ICMP *header*, not the
    entire packet. If you want to put something in the data portion of the
    packet, you need to allocate a larger buffer.

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  3. Re: Why do a cast type structure to an array in this case?

    On Nov 8, 7:18 pm, Barry Margolin wrote:
    > In article <1194576604.969235.278...@y27g2000pre.googlegroups. com>,
    > K-mart Cashier wrote:
    >
    >
    >
    > > Code:

    >
    > > #define BUFSIZE 1500

    >
    > > char sendbuf[BUFSIZE];

    >
    > > void send_v4(void)
    > > {
    > > int len;
    > > stuct icmp *icmp;

    >
    > > icmp = (struct icmp *) sendbuf;
    > > icmp->icmptype = ICMP_ECHO;
    > > icmp->icmpcode = 0;

    >
    > > /*rest of code*/
    > > }

    >
    > > The question is why force a cast to the array sendbuf? Ie why not do
    > > something like
    > > Code:

    >
    > > void send_v4(void)
    > > {
    > > int len;
    > > stuct icmp *icmp;

    >
    > > icmp->icmptype = ICMP_ECHO;
    > > icmp->icmpcode = 0;

    >
    > > /*rest of code*/
    > > }

    >
    > > I'm just sort of curious because this type of coding move appears in
    > > ping and a lot of unix network printer code.

    >
    > In your version the icmp variable is uninitialized. You can't use it
    > until it points to some valid memory. That's what sendbuf[] is in the
    > original version.
    >
    > You could add the following to your version:
    >
    > icmp = malloc(BUFSIZE);
    > /* rest of code */
    > free(icmp);
    >
    > The difference is that this would require use of malloc() and free()
    > every time your function is called, which can be pretty expensive if
    > it's called often. If the function is not used in multiple threads,
    > it's more efficient to reuse the same sendbuf[] every time.
    >
    > Perhaps what you mean to ask was why you don't write:
    >
    > void send_v4(void)
    > {
    > int len;
    > struct icmp icmp;
    >
    > icmp.icmptype = ICMP_ECHO;
    > icmp.icmpcode = 0;
    >
    > /* rest of code */
    >
    > }
    >


    Yes, that is what I meant to ask. My written communication skills sort
    of blow some days..

    > The reason is that struct icmp only defines the ICMP *header*, not the
    > entire packet. If you want to put something in the data portion of the
    > packet, you need to allocate a larger buffer.
    >


    Okay, that makes sense. There are stll some programming techniques
    that elude me. However, I'll save those questions for another time.





  4. Re: Why do a cast type structure to an array in this case?

    On Thu, 08 Nov 2007 18:50:04 -0800, K-mart Cashier
    wrote in comp.programming:

    >
    > Code:
    >
    > #define BUFSIZE 1500
    >
    > char sendbuf[BUFSIZE];
    >
    > void send_v4(void)
    > {
    > int len;
    > stuct icmp *icmp;
    >
    > icmp = (struct icmp *) sendbuf;
    > icmp->icmptype = ICMP_ECHO;
    > icmp->icmpcode = 0;
    >
    > /*rest of code*/
    > }
    >
    >
    > The question is why force a cast to the array sendbuf?


    [snip]

    It is written by programmers who think perceived efficiency is more
    important than portability. The C language does not guarantee that an
    array of characters is properly aligned for a struct icmp. And I
    don't believe POSIX does either, although I might be wrong about that.
    If any of the members of a struct icmp have a size greater than one
    byte, there is the possibility of generating a hardware fault on some
    architectures if the address is misaligned.

    Possible the programmer has verified that there are compiler
    guarantees for every processor and compiler that this code will ever
    be used on that the alignment of sendbuf will be correct, but I
    seriously doubt it. I imagine the alignment issue was never
    considered, but so far it just happens to "work" on the platforms
    where it has been built.

    On the other hand, if the allocated the block just once, they would be
    guaranteed proper alignment, now and forever, even on processors and
    compilers that don't even exist today.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c++-faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html

  5. Re: Why do a cast type structure to an array in this case?

    Jack Klein writes:
    > On Thu, 08 Nov 2007 18:50:04 -0800, K-mart Cashier
    > wrote in comp.programming:
    >
    >>
    >> Code:
    >>
    >> #define BUFSIZE 1500
    >>
    >> char sendbuf[BUFSIZE];
    >>
    >> void send_v4(void)
    >> {
    >> int len;
    >> stuct icmp *icmp;
    >>
    >> icmp = (struct icmp *) sendbuf;
    >> icmp->icmptype = ICMP_ECHO;
    >> icmp->icmpcode = 0;
    >>
    >> /*rest of code*/
    >> }
    >>
    >>
    >> The question is why force a cast to the array sendbuf?

    >
    > [snip]
    >
    > It is written by programmers who think perceived efficiency is more
    > important than portability.


    There is nothing in the code which would lend itself to this
    conclusion.

    > The C language does not guarantee that an array of characters is
    > properly aligned for a struct icmp.


    Insofar this is would be of concern, various more or less 'portable'
    solution would be possible, for instance

    union {
    struct icmp hdr;
    char buf[1500]
    }

    > Possible the programmer has verified that there are compiler
    > guarantees for every processor and compiler that this code will ever
    > be used on that the alignment of sendbuf will be correct,


    Presumably, the programmer (either knowling or unknowlingy) is relying
    on the compiler insofar as to allocate objects in the program data
    segment on word boundaries.

    > I imagine the alignment issue was never considered, but so far it
    > just happens to "work" on the platforms where it has been built.


    In other words: The array is not actually misaligned on any 'supported
    platform' for this (unknown) piece of software. Porting the code to
    some unsupported platform may well involve ... actually changing it.

    > On the other hand, if the allocated the block just once, they would be
    > guaranteed proper alignment, now and forever, even on processors and
    > compilers that don't even exist today.


    This would come at the expense of various other 'unpleasant side
    effect' of abusing the malloc-allocator for static one-time
    allocations. Eg Gnu malloc always aligns on 8 octet boundaries, no
    matter of the actual target platform needs that much or not, a single
    'static lifetime' allocation may tie down as much as a complete page
    of memory unavailable for other uses until the death of the programm
    (and the code may well be old enough for this to still be of concern
    even on then-common 'end user computing platforms') etc.

    As I have recently written in another posting: People writing programs
    with storage requirements which can be met by 'call malloc whenever you
    feel like it' and 'occasionally forget to call free' should not be
    using languages compiled to native machine code anymore. In other
    cases, trading measurable efficency for perceived portability is usually
    bad.

  6. Re: Why do a cast type structure to an array in this case?

    On Nov 9, 4:43 am, Rainer Weikusat wrote:
    > Jack Klein writes:
    > > On Thu, 08 Nov 2007 18:50:04 -0800, K-mart Cashier
    > > wrote in comp.programming:

    >
    > >> Code:

    >
    > >> #define BUFSIZE 1500

    >
    > >> char sendbuf[BUFSIZE];

    >
    > >> void send_v4(void)
    > >> {
    > >> int len;
    > >> stuct icmp *icmp;

    >
    > >> icmp = (struct icmp *) sendbuf;
    > >> icmp->icmptype = ICMP_ECHO;
    > >> icmp->icmpcode = 0;

    >
    > >> /*rest of code*/
    > >> }

    >
    > >> The question is why force a cast to the array sendbuf?

    >
    > > [snip]

    >
    > > It is written by programmers who think perceived efficiency is more
    > > important than portability.

    >
    > There is nothing in the code which would lend itself to this
    > conclusion.
    >
    > > The C language does not guarantee that an array of characters is
    > > properly aligned for a struct icmp.

    >
    > Insofar this is would be of concern, various more or less 'portable'
    > solution would be possible, for instance
    >
    > union {
    > struct icmp hdr;
    > char buf[1500]
    > }
    >


    How can something like

    union {
    struct icmp hdr;
    char buf[1500]
    }

    be less portable?


  7. Re: Why do a cast type structure to an array in this case?

    Chad said:

    >
    > How can something like
    >
    > union {
    > struct icmp hdr;
    > char buf[1500]
    > }
    >
    > be less portable?


    Er, because it doesn't compile? :-)


    --
    Richard Heathfield
    Email: -http://www. +rjh@
    Google users:
    "Usenet is a strange place" - dmr 29 July 1999

  8. Re: Why do a cast type structure to an array in this case?

    Chad writes:
    > On Nov 9, 4:43 am, Rainer Weikusat wrote:


    [...]

    >> Insofar this is would be of concern, various more or less 'portable'
    >> solution would be possible, for instance
    >>
    >> union {
    >> struct icmp hdr;
    >> char buf[1500]
    >> }
    >>

    >
    > How can something like
    >
    > union {
    > struct icmp hdr;
    > char buf[1500]
    > }
    >
    > be less portable?


    It is more or less 'portable' (presumingly, a Germanism, meaning
    'somewhat portable and somewhat nonportable'). The char buffer will be
    aligned as a struct icmp requires, but 6.5.16.1|3 of ISO-C says that:

    If the value being stored in an object is read from another
    object that overlaps in any way the storage of the first
    object, then the overlap shall be exact and the two objects
    shall have qualified or unqualified versions of a compatible
    type; otherwise, the behavior is undefined.

    So, this doesn't help much if "possible limitations of an ISO-compliant
    C-implementation" were an issue.

  9. Re: Why do a cast type structure to an array in this case?

    Richard Heathfield writes:
    > Chad said:
    >
    >>
    >> How can something like
    >>
    >> union {
    >> struct icmp hdr;
    >> char buf[1500]
    >> }
    >>
    >> be less portable?

    >
    > Er, because it doesn't compile? :-)


    This actually makes it highly portable, because it will compile
    nowhere.

  10. Re: Why do a cast type structure to an array in this case?

    Rainer Weikusat wrote:
    > Chad writes:
    >> On Nov 9, 4:43 am, Rainer Weikusat wrote:

    >
    > [...]
    >
    >>> Insofar this is would be of concern, various more or less 'portable'
    >>> solution would be possible,


    >> How can something like


    >> union {


    >> be less portable?


    > It is more or less 'portable' (presumingly, a Germanism, meaning
    > 'somewhat portable and somewhat nonportable').


    "More or less" is certainly, in English, an idiomatic phrase that
    means "somewhat" or "to some extent".

    Whether it came from German is an interesting question. No doubt
    English has been influenced by Germanic languages. But from what
    I could quickly dig up, it seems that many languages have an analog
    to English "more or less", not just German. The best source I could
    find on the Internet was the "Kernerman English Multilingual Dictionary"
    section of this page:

    http://dictionary.reference.com/browse/more%20or%20less

    I'm not really a polyglot, but I could recognize or reasonably guess
    that at least the Danish, Dutch, French, German, Italian, Norwegian,
    Portuguese, Spanish, and Swedish as being, well, more or less direct
    literal analogs of the English phrase, all of them being of the form
    "adverb conjunction adverb" with the adverbs having opposite meaning.
    Since it is so widespread in such a variety of languages, I would
    guess it might be a fairly old phrase that might even predate a lot
    of the languages. (But that's purely a guess.)

    - Logan

+ Reply to Thread