valid static-initializer list values...

Discussion in 'C Programming' started by Chris Thomasson, Mar 19, 2008.

  1. Simple question, does the program below fall victim to undefined-behavior?
    ___________________________________________________________________
    #include <stdio.h>
    #include <assert.h>


    typedef struct fooa_s fooa;
    typedef struct foob_s foob;


    struct fooa_s {
    int whatever;
    };


    struct foob_s {
    fooa fooa_;
    fooa* pfooa;
    };
    #define FOOB_STATICINIT(mp_this) { \
    { 0 }, &(mp_this)->fooa_ \
    }


    static foob g_foob = FOOB_STATICINIT(&g_foob);


    int main(void) {
    printf("(%p/%p/%p) == (&g_foob/&g_foob.fooa_/g_foob.pfooa)\n",
    (void*)&g_foob, (void*)&g_foob.fooa_, (void*)&g_foob.pfooa);
    assert(&g_foob.fooa_ == g_foob.pfooa);

    /*-------------------------------------------------------*/
    puts("\n\n____________________________________________\n\
    press <ENTER> to exit...");
    getchar();
    return 0;
    }

    ___________________________________________________________________




    --
    Chris M. Thomasson
    http://appcore.home.comcast.net
     
    Chris Thomasson, Mar 19, 2008
    #1
    1. Advertising

  2. "Chris Thomasson" <> wrote in message
    news:...
    > Simple question, does the program below fall victim to undefined-behavior?
    > ___________________________________________________________________

    [...]
    >
    > int main(void) {
    > printf("(%p/%p/%p) == (&g_foob/&g_foob.fooa_/g_foob.pfooa)\n",
    > (void*)&g_foob, (void*)&g_foob.fooa_, (void*)&g_foob.pfooa);

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    DAMN! Why did I print the value of '&g_foob.pfooa'? crap. Anyway, it should
    print the value of 'g_foob.pfooa'.


    [...]
    > return 0;
    > }
    >
    > ___________________________________________________________________





    Here is the fixed version:
    ___________________________________________________________________
    #include <stdio.h>
    #include <assert.h>


    typedef struct fooa_s fooa;
    typedef struct foob_s foob;


    struct fooa_s {
    int whatever;
    };


    struct foob_s {
    fooa fooa_;
    fooa* pfooa;
    };
    #define FOOB_STATICINIT(mp_this) { \
    { 0 }, &(mp_this)->fooa_ \
    }


    static foob g_foob = FOOB_STATICINIT(&g_foob);


    int main(void) {
    printf("(%p/%p/%p) == (&g_foob/&g_foob.fooa_/g_foob.pfooa)\n",
    (void*)&g_foob, (void*)&g_foob.fooa_, (void*)g_foob.pfooa);
    assert(&g_foob.fooa_ == g_foob.pfooa);

    /*-------------------------------------------------------*/
    puts("\n\n____________________________________________\n\
    press <ENTER> to exit...");
    getchar();
    return 0;
    }

    ___________________________________________________________________



    Sorry about that.
     
    Chris Thomasson, Mar 19, 2008
    #2
    1. Advertising

  3. On Tue, 18 Mar 2008 21:52:41 -0700, Chris Thomasson wrote:
    > Simple question, does the program below fall victim to
    > undefined-behavior?

    [...]
    > struct foob_s {
    > fooa fooa_;
    > fooa* pfooa;
    > };
    > #define FOOB_STATICINIT(mp_this) { \
    > { 0 }, &(mp_this)->fooa_ \
    > }
    >
    >
    > static foob g_foob = FOOB_STATICINIT(&g_foob);


    So,

    static foob g_foob = { \
    { 0 }, &(&g_foob)->fooa_ \
    }

    This is fine. You can use -> in constant expressions, so long as you
    don't try to read from any object. Since you only use -> to immediately
    take the result's address, there's no problem.
     
    Harald van Dijk, Mar 19, 2008
    #3
  4. "Harald van Dijk" <> wrote in message
    news:9fa4f$47e0a176$541dfcd3$1.nb.home.nl...
    > On Tue, 18 Mar 2008 21:52:41 -0700, Chris Thomasson wrote:
    >> Simple question, does the program below fall victim to
    >> undefined-behavior?

    > [...]
    >> struct foob_s {
    >> fooa fooa_;
    >> fooa* pfooa;
    >> };
    >> #define FOOB_STATICINIT(mp_this) { \
    >> { 0 }, &(mp_this)->fooa_ \
    >> }
    >>
    >>
    >> static foob g_foob = FOOB_STATICINIT(&g_foob);

    >
    > So,
    >
    > static foob g_foob = { \
    > { 0 }, &(&g_foob)->fooa_ \
    > }
    >
    > This is fine. You can use -> in constant expressions, so long as you
    > don't try to read from any object. Since you only use -> to immediately
    > take the result's address, there's no problem.


    Okay; here is another one:
    ________________________________________________________________
    #include <stdio.h>
    #include <stddef.h>
    #include <assert.h>


    #define MEM_ALIGN(mp_ptr, mp_align) ( \
    (((ptrdiff_t)(mp_ptr)) % (mp_align)) \
    ? (void*)(((ptrdiff_t)(mp_ptr)) + (mp_align) - \
    (((ptrdiff_t)(mp_ptr)) % (mp_align))) \
    : (mp_ptr) \
    )


    #define MEM_BUF_SZ() 32768


    typedef struct mem_heap_s mem_heap;


    struct mem_heap_s {
    unsigned char rawbuf[MEM_BUF_SZ()];
    unsigned char* alignbuf;
    };
    #define MEM_HEAP_STATICINIT(mp_this, mp_align) { \
    { '\0' }, MEM_ALIGN((mp_this)->rawbuf, (mp_align)) \
    }


    int main(void) {
    mem_heap page_heap = MEM_HEAP_STATICINIT(&page_heap, 4096);
    mem_heap l2cache_heap = MEM_HEAP_STATICINIT(&l2cache_heap, 128);

    printf("(%p/%p)-page_heap.rawbuf/page_heap.alignbuf\n",
    (void*)page_heap.rawbuf, (void*)page_heap.alignbuf);

    printf("(%p/%p)-l2cache_heap.rawbuf/l2cache_heap.alignbuf\n",
    (void*)l2cache_heap.rawbuf, (void*)l2cache_heap.alignbuf);

    assert(! (((ptrdiff_t)page_heap.alignbuf) % 4096));
    assert(! (((ptrdiff_t)l2cache_heap.alignbuf) % 128));


    /*---------------------------------------------------------*/
    puts("\n\n\n______________________________________________\n\
    press <ENTER> to exit...");
    getchar();
    return 0;
    }

    ________________________________________________________________


    Is there anything wrong with that?
     
    Chris Thomasson, Mar 29, 2008
    #4
  5. "Chris Thomasson" <> wrote in message
    news:...
    > "Harald van Dijk" <> wrote in message
    > news:9fa4f$47e0a176$541dfcd3$1.nb.home.nl...
    >> On Tue, 18 Mar 2008 21:52:41 -0700, Chris Thomasson wrote:
    >>> Simple question, does the program below fall victim to
    >>> undefined-behavior?

    [...]
    >> This is fine. You can use -> in constant expressions, so long as you
    >> don't try to read from any object. Since you only use -> to immediately
    >> take the result's address, there's no problem.

    >
    > Okay; here is another one:
    > ________________________________________________________________

    [...]
    > ________________________________________________________________
    >
    >
    > Is there anything wrong with that?


    When I compile this with Comeau I get the following output:
    ________________________________________________________________
    Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
    Copyright 1988-2007 Comeau Computing. All rights reserved.
    MODE:strict errors C99 noC++0x_extensions

    "ComeauTest.c", line 39: warning: invalid format string conversion
    assert(! (((ptrdiff_t)page_heap.alignbuf) % 4096));
    ^

    "ComeauTest.c", line 40: warning: invalid format string conversion
    assert(! (((ptrdiff_t)l2cache_heap.alignbuf) % 128));
    ^
    ________________________________________________________________


    I am not exactly sure what to make of them; any ideas?
     
    Chris Thomasson, Mar 29, 2008
    #5
  6. "Chris Thomasson" <> wrote in message
    news:...
    > "Harald van Dijk" <> wrote in message
    > news:9fa4f$47e0a176$541dfcd3$1.nb.home.nl...
    >> On Tue, 18 Mar 2008 21:52:41 -0700, Chris Thomasson wrote:
    >>> Simple question, does the program below fall victim to
    >>> undefined-behavior?

    [...]
    >> This is fine. You can use -> in constant expressions, so long as you
    >> don't try to read from any object. Since you only use -> to immediately
    >> take the result's address, there's no problem.

    >
    > Okay; here is another one:
    > ________________________________________________________________

    [...]
    > ________________________________________________________________
    >
    >
    > Is there anything wrong with that?


    Well, this is definitely not going to work. I wanted to be able to fully
    initialize 'mem_heap' objects using an initializer list so that I could
    avoid calling an explicit 'mem_heap_init()' function; oh well.

    ;^(
     
    Chris Thomasson, Mar 29, 2008
    #6
    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. Ed Thompson

    static initializer vs constructor

    Ed Thompson, Oct 9, 2004, in forum: Java
    Replies:
    9
    Views:
    925
    Chris Uppal
    Oct 11, 2004
  2. Replies:
    6
    Views:
    381
    Gabriel
    Jan 25, 2006
  3. Marvin Barley
    Replies:
    6
    Views:
    396
    Marvin Barley
    Feb 19, 2007
  4. chucky
    Replies:
    14
    Views:
    1,290
    Twisted
    Aug 2, 2007
  5. joes
    Replies:
    3
    Views:
    316
Loading...

Share This Page