How to disable macro function? - macros

Is it OK to set debugging macros to empty string when I want to disable debug checks?
Both assert and BOOST_ASSERT are set to ((void)0) when NDEBUG is defined.
Why not to do something line this?
#ifdef NDEBUG
#define MY_DEBUG_MACRO_FUNCTION(x,y,z) ""
#elif
// define macros
#endif

The idea is for the macro to do nothing on release builds. You could define it to an empty string literal, since ""; is a valid expression. I would believe the reason of being defined to ((void)0) is so that the implementation does not emmit warnings for the expression. I have no solid grounds to say this, but some minimal testing shows that ""; generates a warning while ((void)0) doesn't. Of course, warnings are not standarized so there could be a particular implementation that does emit a warning for ((void)0) as well, but it would have to define assert to something else that doesn't on NDEBUG builds or it would be quite annoying to the user.

Not it's not ok. But you can make the "body" of the macro empty:
#define MY_DEBUG_MACRO_FUNCTION(x,y,z)
Note that there is nothing being defined, so when used nothing will be put in the source.

Going by your subject line use #undef. This is useful when there is a macro version and a C version of the function. This way you can use the compiled code over the in-lined expanded macro.

Related

Swift replacement for Objective-C macro

I busy rewriting an app in Swift and would like to convert the following macro to Swift code.
#define FLOG(format, ...) NSLog(#"%#.%# %#", [self class], NSStringFromSelector(_cmd), [NSString stringWithFormat:format, ##__VA_ARGS__])
How can I define this as a Swift function such that I can use if anywhere for debug logging purposes, or is there an alternate way to achieve the same thing?
The easiest way is probably to take advantage of string interpolation and use:
func FLOG(message:String, method:String = __FUNCTION__) {
println("\(method): \(message)")
}
Then you usage is similar to:
FLOG("Illegal value: \(value)")
Having the method argument default to __FUNCTION__ means that it will normally be replaced with the calling function name. Other automatic variables that you could use include __FILE__, __LINE__ and __COLUMN__. Unfortunately __PRETTY_FUNCTION__ is no longer available.
If you want more control over the formatting of the message than string interpolation allows, take a look at this question which demonstrates simplifying access to printf-style formatting in Swift, and would let you do:
FLOG("Illegal value: %x" % [value])
See also this post from Apple that addresses using __FILE__ and __LINE__ in assert
Apple's answer to the removal of macros and something new to replace them is that nothing like macros will be available in swift. The closest you can get is to replace #define with a global let variable.
Example: instead of #define CONSTANT 0 you can write let CONSTANT = 0
Whereas, if you want to pass arguments inside a macro, that feature will no longer be available as considered bad programming practice. What you can do instead is create a function.

Does Clang support conditional macro expansion?

By Conditional Macro Expansion, I means something like this:
XXX(_arg) => AAA(_arg), if _arg > 0
XXX(_arg) => BBB(_arg), otherwise
To be more specific, AAA and BBB are not functions but are attribute specifiers—__attribute__ ((attribute-list)), so runtime branching does not work.
Is is possible to write macros like this? If so, how?
I imagine that it is obvious that you can write:
#define XXX(arg) ((arg) > 0) ? AAA(arg) : BBB(arg))
This is the simple way to do it. If arg is a compile-time constant, you will get only one of the two possible function calls in the code. If you want to try for an alternative, investigate the Boost Preprocessor package, and in particular IF and IIF. It works with C as well as C++.
(I renamed _arg to arg to avoid collisions with names reserved to the implementation. I'm not sure it actually matters in this context, but I'd steer clear of names starting with an underscore.)
The usual trick in this case is to use token-pasting in a way that makes your macros sort of "polymorphic". For example:
#define IFtrue(a,b) a
#define IFfalse(a,b) b
#define IF(x,a,b) IF##x(a,b)
IF(true, int, double) IF(false, foo(), main()) { }
Unfortunately, this works only if your "condition" is literally the word true or the word false; it doesn't work for things like a > 0.
What is the exact problem you're trying to solve? There's probably a better approach.

Replace a macro with a different definition in Eclipse?

I'm working on a project which defines globals like this:
// Define an correctly-sized array of pointers to avoid static initialization.
// Use an array of pointers instead of an array of char in case there is some alignment issue.
#define DEFINE_GLOBAL(type, name, ...) \
void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
Which apparently works fine, but causes Eclipse to show every single usage of one of these globals as an error.
I would prefer that it be this:
#define DEFINE_GLOBAL(type, name, ...) \
type name;
But I can't change this file, so is there a way to tell Eclipse to pretend that that's the macro's definition?
If you #define the preferred definition after the initial (unwanted) definition, Eclipse seems to use the most recent definition when it does the dynamic macro expansion.
Thus, if you re-#define the macro in the file you are editing, this may solve your problem.
Granted that this is a kludge and may cause unforeseen problems, it may work for your implementation.

Initialiser element is not a compile time constant

In my constant file, I have included the below line
NSString * ALERT_OK = NSLocalizedString(#"Ok",#"Ok");
After this, when I tried to compile I am receiving the below error
Initialiser element is not a compile time constant
How can I debug this?
The problem is that NSLocalizedString is a function which returns different values, depending on the language. It is not a constant which can be figured out until the system is running.
Instead, use:
#define ALERT_OK NSLocalizedString(#"Ok",#"Ok");
And it will now simply replace ALERT_OK with the function and you will be fine. (Note that you should be using some kind of prefix to all global values like this so that you don't accidentally create something with the same name being used somewhere else.)

How to make a macro which gives back a string into the source code?

Example: I want to do this:
METHODNAME(5) {
// do something
}
which results in:
- (void)animationStep5 {
// do something
}
Is there any way to do this? Basically, what I need is a way to generate a real source code string before the program is compiled, so the compiler does see - (void)animationStep5...
Or maybe there's something different than a macro, which can help here to auto-generate method names (not at run-time)?
As was already answered here, the objective-C preprocessor is very close to the C one.
You should have a look at the examples posted there, and have a look at C proprocessor. You will simply have to use the ## syntax of the preprocessor, to concatenate the method name, and the number you want.
You can use the concatenation operator
#define METHODNAME(i) -(void)animationStep##i
you can call it like
METHODNAME(5){}
This expands to
-(void)animationStep5{}
Assuming the objective-c preprocessor behaves the same as the standard C one, you can use something like:
#define PASTE(a, b) a##b
#define METHODNAME(n) PASTE(animationStep,n)
to join the required bits together. This means that
METHODNAME(5)
gets translated to
animationStep5
(you may need to add the "void" from your question to the macro definitino depending on exactly what it is you need to do).