merits of "#define", "const", and "enum" ??? 
Author Message
 merits of "#define", "const", and "enum" ???

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

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.

QUESTION: IS THERE A BETTER WAY... ???

--

Randy Selzler, rm 2A11         |   for rent ...
Amoco Tulsa Technology Center  |   (918)660-3413
Tulsa, OK 74102-3385           |



Mon, 08 Dec 1997 03:00:00 GMT  
 merits of "#define", "const", and "enum" ???


Quote:

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

Actually, conventional wisdom says use a #define in cases where you
can't use an enum.  *NEVER* use 'const int' to mean a compile time constant.

Quote:
> [ reasons you wouldn't want to use 'const int' as a compile time constant ]

>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, you can also do:

enum { flag = 4 };
#define FLAG ((size_t)flag)

which at least has a symbolic name in de{*filter*}s.
--
---
Tim Hollebeek                   'There will be a better sig when I have time'



Mon, 08 Dec 1997 03:00:00 GMT  
 merits of "#define", "const", and "enum" ???

Quote:
Hollebeek) writes:



<snip>
|> >
|> >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, you can also do:
|>
|> enum { flag = 4 };
|> #define FLAG ((size_t)flag)
|>
|> which at least has a symbolic name in de{*filter*}s.

Or better still, prototype func, so that the compiler will change from an
integer to size_t for you.

Cheers
Tanmoy
--

Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87544-0285,USA H:#3,802,9 St,NM87545
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
< http://www.*-*-*.com/ ;or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- < http://www.*-*-*.com/ ;
fax: 1 (505) 665 3003   voice: 1 (505) 665 4733    [ Home: 1 (505) 662 5596 ]



Tue, 09 Dec 1997 03:00:00 GMT  
 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.



Fri, 12 Dec 1997 03:00:00 GMT  
 merits of "#define", "const", and "enum" ???

: 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".

How can you optimize the number 4? :)

Scott



Sun, 14 Dec 1997 03:00:00 GMT  
 merits of "#define", "const", and "enum" ???


Quote:

>: 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".

>How can you optimize the number 4? :)

>Scott

Consider FLAG + 1.  In the first case, it's (FLAG + 1), which requires
the addition to be done at runtime b/c the compiler doesn't know what
FLAG is.  With a #define, the compiler can say 'Ah!  4 + 1!  That's 5!'

--
---
Tim Hollebeek                   'There will be a better sig when I have time'



Mon, 15 Dec 1997 03:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. merits of "#define",

2. remove() vrs fopen("""w")

3. Displaying binary data as ascii "1"'s and "0"'s

4. Looking for "Shroud"/"Obfus"

5. ""help with TSR""

6. Parse trees and "("")"

7. Error "free"-ing "malloc"-ed memory

8. Displaying binary data as ascii "1"'s and "0"'s

9. "#define" versus "con

10. pass "double *const *" ptr to fn expecting "const double *const *"

11. Attention "C"/"C++" gurus and "C" newbees

12. why not "cout", "<<" , and "endl"??

 

 
Powered by phpBB® Forum Software