Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
189 views
in Technique[技术] by (71.8m points)

c++ - Use #ifdefs and #define to optionally turn a function call into a comment

Is it possible to do something like this

#ifdef SOMETHING
#define foo //
#else
#define foo MyFunction
#endif

The idea is that if SOMETHING is defined, then calls to foo(...) become comments (or something that doesn't get evaluated or compiled), otherwise it becomes a call to MyFunction.

I've seen __noop used, but I don't believe I can use that.

EDIT(s):

I don't think I can really use a macro here, because MyFunction takes a variable number of arguments.

Also, I'd like to make it so the arguments are NOT evaluated! (So doing something like commenting out the body of MyFunction doesn't really give me what I need, as the arguments will still be evaluated)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try this:

#ifdef SOMETHING
#define foo(x)
#else
#define foo(x) MyFunction(x)
#endif

If your function has several arguments, then:

#ifdef SOMETHING
#define foo(x,y,z)
#else
#define foo(x,y,z) MyFunction(x,y,z)
#endif

If your function has a variable number of arguments, then your compiler may support so-called "variadic macros", like this:

#ifdef SOMETHING
#define foo(...)
#else
#define foo(...) MyFunction(__VA_ARGS__)
#endif

The reason which I've seen this kind of thing used in practice is to get rid of logging functions from a release build. However, see also Separate 'debug' and 'release' builds? in which people question whether you should even have different builds.


Alternatively, instead of redefining the function call as nothing, Jonathan's comment to this answer suggested doing something like the following:

#ifdef SOMETHING
#define foo(...) do { if (false) MyFunction(__VA_ARGS__) } while (0)
#else
#define foo(...) do { if (true) MyFunction(__VA_ARGS__) } while (0)
#endif

The reasoning for doing this is so that the function call is always compiled (so it won't be left with gratuitous errors like references to deleted variables), but only called when needed: see Kernighan & Pike The Practice of Programming and also the Goddard Space Flight Center programming standards.

From a debug.h file (originating from 1990, and therefore not using __VA_ARGS__):

/*
** Usage:  TRACE((level, fmt, ...))
** "level" is the debugging level which must be operational for the output
** to appear. "fmt" is a printf format string. "..." is whatever extra
** arguments fmt requires (possibly nothing).
** The non-debug macro means that the code is validated but never called.
** -- See chapter 8 of 'The Practice of Programming', by Kernighan and Pike.
*/
#ifdef DEBUG
#define TRACE(x)    db_print x
#else
#define TRACE(x)    do { if (0) db_print x; } while (0)
#endif /* DEBUG */

With C99, there's no longer a need for the double parentheses trick. New code should not use it unless C89 compatibility is an issue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...