valid static-initializer list values...

C

Chris Thomasson

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;
}

___________________________________________________________________
 
C

Chris Thomasson

Chris Thomasson said:
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.
 
H

Harald van Dijk

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.
 
C

Chris Thomasson

Harald van Dijk said:
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?
 
C

Chris Thomasson

Chris Thomasson said:
Harald van Dijk said:
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?
 
C

Chris Thomasson

Chris Thomasson said:
Harald van Dijk said:
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.

;^(
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,142
Latest member
arinsharma
Top