Pedantic about an extra `;' inside class declaration

M

Miguel Guedes

Consider the following snippet of code,

#ifdef DEBUG

# define DUMP_DECLARE() public: \
virtual void dump() const

#else

# define DUMP_DECLARE()

#endif // DEBUG


The above macro is used in (some) class declarations like so,

class Bar
{
..
:
..

DUMP_DECLARE();
};


The above compiles fine when DEBUG is defined, however when it is not
defined the compiler spits out warnings complaining about an extra `;',
as given:

.../../src/language.hxx:56:8: warning: extra ';' inside a class [-pedantic]
public:;
^
.../../src/language.hxx:57:17: warning: extra ';' inside a class [-pedantic]
DUMP_DECLARE();


I could easily overcome this warning by making it so that DUMP_DECLARE
never requires a semi-colon at the end:

#define DUMP_DECLARE public: \
virtual void dump() const;

class Bar
{
DUMP_DECLARE()
};


However I thought of asking the comp.lang.c++ experts if there is any
way to overcome this pedantic warning when using the first macro form
that requires the semi-colon. In particular, is there some sort of
declaration similar to (void(0)) that I could employ?
 
I

Ian Collins

Miguel said:
Consider the following snippet of code,

#ifdef DEBUG

# define DUMP_DECLARE() public: \
virtual void dump() const

#else

# define DUMP_DECLARE()

#endif // DEBUG

Why don't you forget the macro and simply omit the *definition* of
dump() when DEBUG isn't defined?
 
M

Miguel Guedes

The semicolon irritation by itself is a minor one. However, I see more
serious problems with your approach. First, this makes the vtable layout
different in DEBUG and non-DEBUG builds. This may cause some problems
which would not arise otherwise. For example, you might want to compile a
single source file in DEBUG mode, for better debugging possibilities, or
compile a too-slow source file in non-DEBUG mode in the otherwise DEBUG
build. Or maybe you want to mix shared libraries from different builds
by any reason. With the above macro this is just not possible.

Although at this time I don't envision any of the use case possibilities
you enumerated ever becoming reality, it is true that my approach is
just logically inconsistent; definitely not the elegant solution I was
hoping for and so I'm ditching it.
This macro also inserts 'public:' in one mode and not in other, which may
cause incompatibilities between builds.

So, the suggested fix is to always occupy the same vtable slot and use
the same function signature. If you insist of getting compile-time errors
if dump() is called in the non-DEBUG build you can name the function
differently. The actual function may be defined as a non-op or left
undefined, depending on how much do you want to support mixed builds and
wander into implementation-defined behavior.

#ifdef DEBUG

# define DUMP_DECLARE() public: \
virtual void dump() const

#else

# define DUMP_DECLARE() public: \
virtual void dummy_do_not_call() const

#endif // DEBUG

Incidentally, this solves the semicolon problem as well.

It certainly does! Thank you for the input, Paavo & everybody.
 
M

Miguel Guedes

And what exactly is the problem with it, that you are trying to solve?

Just me being pedantic. Since statements in C++ require a semi-colon at
the end (or be separated by one) I thought the solution you quoted above
just wasn't logically consistent.
 

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
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top