libs and constants

S

SerGioGio

Hello,

I want to build a ".lib" library where I will have some constants.
The constants are not only int, char, but also struct constants.
How do I declare / implement these struct constants? I came up with 3
solutions but I am really satisfied with none of them:

1. use #define
This can work with constants int or char*, but not really with structures.
If you have
| #define my_struct_constant { { 1, 2 }, 3 }

you can then write
| my_struct constant = my_struct_constant;
but subsequentely you cannot write
| constant = my_struct_constant;

2. declare the variable in .h:
| extern my_struct my_struct_constant;
and implement in a .c:
| my_struct my_struct_constant = { { 1, 2 }, 3 };
you can then write
| my_struct constant = my_struct_constant;
| constant = my_struct_constant;

So far so good.
But I understand however that the initialisation will not be performed...
So I will need to provide an init() function and require the users of the
..lib to call these function...
In addition I will need two lines in two separate files (declaration /
implementation) so it is harder to maintain.

3. provide a make function
| extern my_struct make_my_struct(int, int, int);
and use #define:
| #define my_struct_constant make_my_struct(1, 2, 3)
you can then write
| my_struct constant = my_struct_constant;
| constant = my_struct_constant;
But this does not scale very well, you need to provide make functions for
all the types you will have constants.

Are there any better options than thses ones?

Thanks in advance for your comments and suggestions!

SerGioGioGio
 
C

Chris Torek

I want to build a ".lib" library where I will have some constants.
The constants are not only int, char, but also struct constants.

Only C99 has actual support for structure-valued constants.

If all of your compilers support (at least this much) C99, you
can write, e.g.:

#define ZORG ((const struct evil) {{ 1, 2 }, 3 })

(The "const" is not required, but I consider it a good idea.)

Note that the user of this constant must take care to avoid
taking the address of the constant, which does work but may
point to an object with automatic storage duration:

#ifdef OLDWAY
typedef double evil_t;
#define ZORG (42.0)
#else
typedef struct evil evil_t;
struct evil { int b[2]; int c; };
#define ZORG ((const struct evil) {{ 1, 2 }, 3 })
#endif

const evil_t *foo(void) {
const evil_t *p;
...
p = &ZORG;
return p; /* ERROR */
}

One cannot take addresses of, e.g., simple int- and double-valued
constants, so programmers are not particularly *likely* to attempt to
take the address of the constant. If one defines OLDWAY above, the
code fails to compile.
 

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,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top