Re: initializing data at compile time
From: Bart Goeman (bg2_at_pandora.be)
Date: 12/31/04
- Next message: dcorbit_at_connx.com: "Re: problem with fgets"
- Previous message: Neil Kurzman: "Re: using 8086 in C"
- In reply to: Bart Goeman: "Re: initializing data at compile time"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Fri, 31 Dec 2004 04:24:56 GMT
Op Mon, 20 Dec 2004 00:40:07 +0000, schreef Bart Goeman:
>> On Sat, 18 Dec 2004 20:48:59 GMT, Bart Goeman <bg2@pandora.be> wrote
>> in comp.lang.c:
>>
>>
>
> this does not work because menus[menuid].n_columnheaders is not
> a constant expression, according to C's interpretation. so I have to use
> normal asserts->wasted code space, wasted run time,
> error has to be reported in a meaningful way->more wasted code...
>
> this is another example of a difficulty with initializing data structures
> in C at compile time for which I do not know a good solution.
i found a solution myself abusing enums.
bash:pan$ cat menu.h
DEFMENU( MENU_CLUTCH,"Clutches",clutchheaders)
DEFMENU( MENU_GEAR,"Gears",gearheaders)
bash:pan$ cat parameter.h
DEFPARAMETER( P_CLUTCHON,"clutch on pressure",clutchon,MENU_CLUTCH)
DEFPARAMETER( P_CLUTCHOFF,"clutch off pressure",clutchoff,MENU_CLUTCH)
DEFPARAMETER( P_GEARPATT,"gear pattern",gearpattern,MENU_GEAR)
bash:pan$ cat main.c
int clutchon[3];
int clutchoff[3];
int gearpattern[4];
extern const char * const clutchheaders[3];
extern const char * const gearheaders[4];
#define SIZE(x) (sizeof(x)/sizeof(x[0]))
#define COMPILE_TIME_ASSERT(x) do \
{ switch (0) case 0: case x: ;} while (0)
struct s_menu
{
const char * name;
const char * const * columnheaders;
int n_columnheaders;
};
//construct an enum for the menu ids
#define DEFMENU(id,name,headers) id,
enum menu_id
{
#include "menu.h"
};
#undef DEFMENU
//initialize menu array
#define DEFMENU(id,name,headers) \
{ name, headers, SIZE(headers) },
const struct s_menu menus[]=
{
#include "menu.h"
};
#undef DEFMENU
struct s_parameter
{
const char * name;
int * p;
int menu;
};
/*
* now we want to test if each parameter has the same number of
* elements as the corresponding header.
*/
/* this test does not compile */
#if 0
#define DEFPARAMETER(id,name,var,menuid) \
COMPILE_TIME_ASSERT(SIZE(var)==menus[menuid].n_columnheaders)
static void compile_time_asserts_fail(void)
{
# include "parameter.h"
};
#undef DEFPARAMETER
#endif
/*but this test does work! */
#define DEFMENU(id,name,headers) \
enum { SIZE_##id = SIZE(headers)};
#define DEFPARAMETER(id,name,var,menuid) \
COMPILE_TIME_ASSERT(SIZE(var)==SIZE_##menuid);
static void compile_time_asserts(void)
{
# include "menu.h"
# include "parameter.h"
};
#undef DEFMENU
#undef DEFPARAMETER
so by declaring an enum for each menu it works.
#define DEFMENU(id,name,headers) \
const int SIZE_##id==SIZE(headers)
is more natural but doesn't work, a const int is not a constant expression.
It's all rather ugly of course.
- Next message: dcorbit_at_connx.com: "Re: problem with fgets"
- Previous message: Neil Kurzman: "Re: using 8086 in C"
- In reply to: Bart Goeman: "Re: initializing data at compile time"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|