Evaluating Preprocessor

Evaluating Preprocessor

Post by pinkfloydh » Sat, 11 Nov 2006 21:32:25


We might use the normal preprocessor something like this

#define WIDTH 42
#define HEIGHT 100
#define AREA (WIDTH*HEIGHT)

To have "42*100" is inserted in the code whereever AREA is used. But
does an evaluating preprocessor exist that can do some evaluation on
expressions so that AREA becomes 4200?

I know that most compilers will figure this out themselves anyway.

And I know that I should use a const instead for this kind of thing.

But in general (for instance with old (C) compilers that don't have
const, or compilers that don't optimize very well), it would be nice to
_know_ that an expression is evaluated before compile-time and runtime.


In general, it would be nice to have a simple and clean turing complete
language for compile time evaluation. I guess I can easily make a
simple but powerful preprocessor in Python that can do this, also for
C/C++ code. But maybe it already exist?

/David
 
 
 

Evaluating Preprocessor

Post by Greg » Sat, 11 Nov 2006 23:53:54


But hopefully you won't.


No, although the preprocessor does evaluate arithmatic expressions in
some contexts (such as, for an #if directive), most of the time it
merely performs textual substitution.


Then why not use const? Doing so would guarantee a compile-time
evaluation of 42 * 100:

const int kWidth = 42;
const int kHeight = 100;
const int kArea = 42 * 100;

Since the compiler needs a constant value for the symbol "kArea" it has
no choice but to multiply 42 by 100 at compile time.


This is a C++ newsgroup, so it seems odd to be asking the best practice
for languages other than C++.

And if you want to know whether 42 * 100 is evaluated at runtime or at
compile time, then just examine a disassembly of a compiled binary to
find out. Alternately you could ask your compiler maker whether the
compiler performs "constant folding" as an optimization. And if it
doesn't, find a better compiler.


I fervently hope that you do have better uses for your time than to
rewrite the C++ preprocessor. Besides, it has been done, only it's
called "C++ template metaprogramming".

template <int N> struct Height
{ static const int value = N; };

template <int N> struct Width
{ static const int value = N; };

template <class H, class W>
struct Area
{
static const int value = H::value * W::value;
};

Area<Height<42>, Width<100> >::value; // 4200

It's possible to perform much more sophisticated (though not
necessarily any less verbose) compile-time calculations with C++
metaprogramming. At least, for those so inclined.

Greg

 
 
 

Evaluating Preprocessor

Post by Greg » Sat, 11 Nov 2006 23:58:00

> #define WIDTH 42

But hopefully, cooler heads will prevail.


No, although the preprocessor does evaluate arithmatic expressions in
some contexts (such as, for an #if directive), most of the time it
merely performs textual substitution.



Then why not use const? Doing so would guarantee a compile-time
evaluation of 42 * 100:

const int kWidth = 42;
const int kHeight = 100;
const int kArea = kWidth * kHeight;

Since the compiler needs a constant value for the symbol "kArea" it has

no choice but to multiply 42 by 100 at compile time.


This is a C++ newsgroup, so it seems odd to be asking the best practice

for languages other than C++.

And if you want to know whether 42 * 100 is evaluated at runtime or at
compile time, then just examine a disassembly of a compiled binary to
find out. Alternately you could ask your compiler maker whether the
compiler performs "constant folding" as an optimization. And if it
doesn't, find a better compiler.


I fervently hope that you do have better uses for your time than to
rewrite the C++ preprocessor. Besides, it has been done, only it's
called "C++ template metaprogramming".

template <int N> struct Height
{ static const int value = N; };

template <int N> struct Width
{ static const int value = N; };

template <class H, class W>
struct Area
{
static const int value = H::value * W::value;
};

Area<Height<42>, Width<100> >::value; // 4200

It's possible to perform much more sophisticated (though not
necessarily any less verbose) compile-time calculations with C++
metaprogramming. At least, for those so inclined.

Greg
 
 
 

Evaluating Preprocessor

Post by Greg » Sun, 12 Nov 2006 00:03:51

We might use the normal preprocessor something like this


But hopefully, cooler heads will prevail.


No, although the preprocessor does evaluate arithmatic expressions in
some contexts (such as, for an #if directive), most of the time it
merely performs textual substitution.



Then why not use const? Doing so would guarantee a compile-time
evaluation of 42 * 100:

const int kWidth = 42;
const int kHeight = 100;
const int kArea = kWidth * kHeight;

Since the compiler needs a constant value for the symbol "kArea" it has
no choice but to multiply 42 by 100 at compile time.


This is a C++ newsgroup, so it seems odd to be asking the best practice
for languages other than C++.

And if you want to know whether 42 * 100 is evaluated at runtime or at
compile time, then just examine a disassembly of a compiled binary to
find out. Alternately you could ask your compiler maker whether the
compiler performs "constant folding" as an optimization. And if it
doesn't, find a better compiler.


I fervently hope that you do have better uses for your time than to
rewrite the C++ preprocessor. Besides, it has been done, only it's
called "C++ template metaprogramming".

template <int N> struct Height
{ static const int value = N; };

template <int N> struct Width
{ static const int value = N; };

template <class H, class W>
struct Area
{
static const int value = H::value * W::value;
};

Area<Height<42>, Width<100> >::value; // 4200

It's possible to perform much more sophisticated (though not
necessarily any less verbose) compile-time calculations with C++
metaprogramming. At least, for those so inclined.

Greg
 
 
 

Evaluating Preprocessor

Post by Greg » Sun, 12 Nov 2006 00:07:23


But hopefully, cooler heads will prevail.


No, although the preprocessor does evaluate arithmatic expressions in
some contexts (such as, for an #if directive), most of the time it
merely performs textual substitution.


Then why not use const? Doing so would guarantee a compile-time
evaluation of 42 * 100:

const int kWidth = 42;
const int kHeight = 100;
const int kArea = kWidth * kHeight;

Since the compiler needs a constant value for the symbol "kArea" it has
no choice but to multiply 42 by 100 at compile time.


This is a C++ newsgroup, so it seems odd to be asking the best practice
for languages other than C++.

And if you want to know whether 42 * 100 is evaluated at runtime or at
compile time, then just examine a disassembly of a compiled binary to
find out. Alternately you could ask your compiler maker whether the
compiler performs "constant folding" as an optimization. And if it
doesn't, find a better compiler.


I fervently hope that you do have better uses for your time than to
rewrite the C++ preprocessor. Besides, it has been done, only it's
called "C++ template metaprogramming".

template <int N> struct Height
{ static const int value = N; };

template <int N> struct Width
{ static const int value = N; };

template <class H, class W>
struct Area
{
static const int value = H::value * W::value;
};

Area<Height<42>, Width<100> >::value; // 4200

It's possible to perform much more sophisticated (though not
necessarily any less verbose) compile-time calculations with C++
metaprogramming. At least, for those so inclined.

Greg