Use of macros in C++?

A

Alex Buell

A previous thread about macros just reminded me to ask this. I have
avoided using macros and defined some constants i.e.:

const int BYTES_PER_TRACK = 10 * 256;
const int TRACK0_SS_OFFSET = 0;
const int TRACK0_SS_OFFSET = 10 * 256;

Now, the problem is that I have several modules in my project that
references these constants, so I have to use 'extern const in
BYTES_PER_TRACK' etc., in the main header file so the constants are
available to other modules.

I feel that in a situation like that wouldn't it be better to use
macros intead? Or not?

Thanks for any insights offered.
 
A

Alf P. Steinbach

* Alex Buell:
A previous thread about macros just reminded me to ask this. I have
avoided using macros and defined some constants i.e.:

const int BYTES_PER_TRACK = 10 * 256;
const int TRACK0_SS_OFFSET = 0;
const int TRACK0_SS_OFFSET = 10 * 256;

Use of all uppercase for names is likely to conflict with macros; it's a
bad idea (see this group's FAQ, and also Bjarne Stroustrup's FAQ).

It's a Java convention, where it isn't a problem because Java doesn't
have a preprocessor.

Java got it from early C (which didn't have 'const', so that the
preprocessor had to be used for constants, where that convention helped
to avoid conflict with ordinary non-preprocessor symbols).

Essentially you've taken something very bad from the mists of historical
time, and reintroduced it in a descendant language of the language where
it originated -- a descendant language that helped to expel the monster.

Don't copy conventions and other things blindly.

Now, the problem is that I have several modules in my project that
references these constants, so I have to use 'extern const in
BYTES_PER_TRACK' etc., in the main header file

Well, other don't have to do that.

so the constants are
available to other modules.

They should be defined or at least declared in a header file, yes.

I feel that in a situation like that wouldn't it be better to use
macros intead? Or not?

Thanks for any insights offered.

Follow the net directions indicated above.
 
R

Roland Pibinger

A previous thread about macros just reminded me to ask this. I have
avoided using macros and defined some constants i.e.:

const int BYTES_PER_TRACK = 10 * 256;
const int TRACK0_SS_OFFSET = 0;
const int TRACK0_SS_OFFSET = 10 * 256;

Now, the problem is that I have several modules in my project that
references these constants, so I have to use 'extern const in
BYTES_PER_TRACK' etc., in the main header file so the constants are
available to other modules.

I feel that in a situation like that wouldn't it be better to use
macros intead? Or not?

Consider using enums:

enum {
BYTES_PER_TRACK = 10 * 256;
TRACK0_SS_OFFSET = 0;
// ...
};

Best wishes,
Roland Pibinger
 
J

John Carson

Alex Buell said:
A previous thread about macros just reminded me to ask this. I have
avoided using macros and defined some constants i.e.:

const int BYTES_PER_TRACK = 10 * 256;
const int TRACK0_SS_OFFSET = 0;
const int TRACK0_SS_OFFSET = 10 * 256;

Now, the problem is that I have several modules in my project that
references these constants, so I have to use 'extern const in
BYTES_PER_TRACK' etc., in the main header file so the constants are
available to other modules.

I feel that in a situation like that wouldn't it be better to use
macros intead? Or not?


Macros are only visible within the translation unit in which they are
#defined, which is the same as const ints (without the extern modifier). So
what advantage do macros offer?
 
A

Alex Buell

Consider using enums:

enum {
BYTES_PER_TRACK = 10 * 256;
TRACK0_SS_OFFSET = 0;
// ...
};

That along with putting it into its own name space might be a better
idea. Thanks.
 
R

Rolf Magnus

Alex said:
A previous thread about macros just reminded me to ask this. I have
avoided using macros and defined some constants i.e.:

const int BYTES_PER_TRACK = 10 * 256;
const int TRACK0_SS_OFFSET = 0;
const int TRACK0_SS_OFFSET = 10 * 256;

Now, the problem is that I have several modules in my project that
references these constants, so I have to use 'extern const in
BYTES_PER_TRACK' etc., in the main header file so the constants are
available to other modules.

I feel that in a situation like that wouldn't it be better to use
macros intead? Or not?

Not. Just define the constant in the header and don't make it extern.
 
A

Alex Buell

Not. Just define the constant in the header and don't make it extern.

My preferred solution is:
namespace DISK
{
enum
{
BYTES_PER_TRACK = 10 * 256,

TRACK0_SS_OFFSET = 0,
TRACK0_DS_OFFSET = 10 * 256
};
};

And refer to them as:

if (ds)
offset = DISK::TRACK0_DS_OFFSET;

It's much nicer.
 
R

Rolf Magnus

Alex said:
My preferred solution is:
namespace DISK
{
enum
{
BYTES_PER_TRACK = 10 * 256,

TRACK0_SS_OFFSET = 0,
TRACK0_DS_OFFSET = 10 * 256
};
};

And refer to them as:

if (ds)
offset = DISK::TRACK0_DS_OFFSET;

It's much nicer.

Not really, IMHO. enum is for enumerated types, not for constants.
 
R

Rolf Magnus

Roland said:
Note that an anonymous ("typeless") enum is used. :)

The enum doesn't _have_ a type, it _is_ a type. It's nameless though. Still,
if you want constants, you should use constants and not enum (nameless or
not).
 
G

Greg

Rolf said:
Not really, IMHO. enum is for enumerated types, not for constants.

I agree. Using enums as constants is a gross misuse of enumerated types
in C++. Enumerated types specifically represent types whose values are
non-numeric by nature. So any time a program explicitly assigns a
specific value to an enum, there is definitely something amiss.

Furthermore there is absolutely no advantage with using enums instead
of constants, since the compiled bits of the program are not affected.
And the reasons are clear: replacing the enum with a const int means
that the address of the constant will not have to be taken (since the
enum it is replacing could not have had its address taken). Ånd there
is no reason for the program to create storage for the constant values
on its own, say, with extern declarations. Instead the const int
definitions should be placed in a header file - that every source that
has need of them - simply includes.

Greg
 
T

Tomás

Alex Buell posted:
A previous thread about macros just reminded me to ask this. I have
avoided using macros and defined some constants i.e.:

const int BYTES_PER_TRACK = 10 * 256;
const int TRACK0_SS_OFFSET = 0;
const int TRACK0_SS_OFFSET = 10 * 256;

Now, the problem is that I have several modules in my project that
references these constants, so I have to use 'extern const in
BYTES_PER_TRACK' etc., in the main header file so the constants are
available to other modules.

I feel that in a situation like that wouldn't it be better to use
macros intead? Or not?

Thanks for any insights offered.

Here's how my own thought processes work:


1) Is it a primitive type? (e.g. int, double, bool)

If so, then proceed to Question 2. If not, then use Strategy 2.1, as
shown below (without paying any attention to the rest of what's written in
Question 2).

2) Will I ever take its address for some reason?

If so then :-

Strategy 2.1) define it in a source file, and declare
it in a header file.

If not, then we're going to define it in a header file (without the need
for a source file). Advance to Question 3.


3) Is it a integer?

If so, use an enum, e.g.:

enum { age = 7; };

If not, then:

static double const monkey = 2343.2342;


(The "static" is redundant, as it's the default for global const variables.)


-Tomás
 
R

Rolf Magnus

Tomás said:
3) Is it a integer?

If so, use an enum, e.g.:

enum { age = 7; };

If not, then:

static double const monkey = 2343.2342;

Why exactly do you feel the need for that rule?
 
P

Phlip

Alex said:
A previous thread about macros just reminded me to ask this. I have
avoided using macros and defined some constants i.e.:

const int BYTES_PER_TRACK = 10 * 256;
const int TRACK0_SS_OFFSET = 0;
const int TRACK0_SS_OFFSET = 10 * 256;

Put these in a header:

static const int BYTES_PER_TRACK = 10 * 256;
static const int TRACK0_SS_OFFSET = 0;
static const int TRACK0_SS_OFFSET = 10 * 256;

That solution is optimum at run-time because each translation unit sees the
correct value - not an extern - and can start to solve the expressions that
use it.

It will slow down compiles if many translation units see it, so only include
it in the ones that need it. Don't throw it into a global-constants.h
file...
 
G

Greg

Phlip said:
Put these in a header:

static const int BYTES_PER_TRACK = 10 * 256;
static const int TRACK0_SS_OFFSET = 0;
static const int TRACK0_SS_OFFSET = 10 * 256;

There's no point adding the superfluous "static" keyword to each
declaration - at best it will have no effect and at worse it could
confuse the compiler.

A const declaration is static by default (that is, by default it has
internal linkage). So it would be strange to see a const declaration
also declared as static in a C++ program (and in fact using the keyword
static in this manner is officially deprecated by the C++ standard -
which is another good reason not to use it).

Greg
 
A

Alex Buell

Not really, IMHO. enum is for enumerated types, not for constants.

Well, I put that into its own namespace as I've mentioned, so is it
really not too evil for you types to even consider?! ;o)
 

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top