
merits of "#define", "const", and "enum" ???
Quote:
>I'm trying to figure out the prefered method for integral constants in headers.
>Conventional wisdom says, prefer "extern const size_t FLAG;", and avoid
>"#define FLAG 4". The down side is that optimizers can't see the "4".
This sounds like conventional C++ wisdom.
I don't agree that this is, in fact, "conventional wisdom" for C.
I see no objection to using preprocessor macros for the simple
substitution of constant values as described here.
In C a "const int" is *not* a "constant-expression" and therefore
cannot be used in several contexts where a #defined constant would
work (these include array declarators and case statments). This
will ensure that you will have to use preprocessor macros for at
least *some* of your integer constants - why not just use it for all
of them.
If what you are really dealing with are bit flags, where one or more
flags may be set, then *please* don't make them enumerated constants
- that will just confuse people (and probably irritate them).
In this case you might want to consider using bit fields.
Quote:
>If I use "static const size_t FLAG = 4;", the optimizer can see the "4",
>but each module that includes the header has its own copy (storage waste)
>and some compilers issue warnings if "FLAG" isn't actually used.
>If I use "typedef enum {FLAG = 4} MISC_CONSTANTS;", the optimizer can
>see the "4", no storage is wasted, however it doesn't guarantee the
>type will be "size_t". To remain portable, users must explicitly cast
>it as in "x = func((size_t)FLAG);", which is a bug-prone nuisance.
Well since your users *should* have a function prototype in scope
that *shouldn't* be a problem, but as far as programming style goes
this is (IMNSHO) a gross misuse of enum.
Quote:
>QUESTION: IS THERE A BETTER WAY... ???
Yes! Use preprocessor macros!!
It is certainly possible to abuse and over-use the preprocessor,
but in this case it is probably the "right" way of doing it.