const vs. #define

Mateusz Loskot mateusz at LOSKOT.NET
Thu Oct 19 14:04:05 EDT 2006


Ed McNierney wrote:
> Mateusz -
> 
> Could you give an example of an error that would be detected using const
> that would not be detected using #define?  I agree with your premise in
> theory, but I'm not sure how that theory applies here.

Ed,

Here are a few:

1) Try to compile and run this:

#define ABC "abc"
char* p = ABC;
*p = '\0';

and then this:

const char* ABC = "abc";
char* p = ABC;
*p = '\0';

2) Here is another type-safety example:

#define NUM 6
enum E { one, two };
void foo(E e) {}
//...instead of foo(int e) where NUM can be passed without warnings
int main()
{
    foo(NUM);
    return 0;
}


3) Here is run-time bug example:

Try to compile this small program with,
next uncomment #define and comment const int and compare results.

#include <stdio.h>
//#define MYCONST 3 + 2;
const int MYCONST = 3 + 2;
int main()
{
    int x = 3 * MYCONST;

    printf("%d\n", x);

    return 0;
}

There are many many possible examples.
Preprocessor is just a text substitution, nothing else,
so it's easy to forget about parenthesis in macros, and other subtle
things hard to debug, ie. breaking "sequence point" behaviors, etc.

Macros are especially evil in C++ (I know, MapServer is written in C),
but just for example:

a) This one, creates identifier mloskot::X
namespace mloskot
{
   const int X = 7979;
}

b) This one creates... just X

namespace mloskot
{
   #define X (1)
}


This problem causes annoying names clashes between libraries.
I've met a number of similar problems when using GEOS with VC++,
here is the story:

http://geos.refractions.net/pipermail/geos-devel/2006-April/002057.html

Please, note the error message:

"error: expected identifier before numeric constant"

It's completely meaningless!
I had to grep through VC++ and MS Platform SDK sources to find out
what's going wrong ;-)

All this because if macros are evil ;-)

Cheers
-- 
Mateusz Loskot
http://mateusz.loskot.net



More information about the mapserver-dev mailing list