Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a macro that can take a string?

Tags:

I'm trying to do something really trivial: A macro that takes an string and prints that to NSLog.

Like this:

#define PRINTTHIS(text) \
    NSLog(@"text");

However, when I try to pass a string to this guy I end up getting "text" printed to the console. Aren't all variables replaced on a string-level inside the macro? How to do that right?

like image 259
Another Registered User Avatar asked Nov 25 '09 00:11

Another Registered User


People also ask

How do you define a string macro?

We can create two or more than two strings in macro, then simply write them one after another to convert them into a concatenated string. The syntax is like below: #define STR1 "str1" #define STR2 " str2" #define STR3 STR1 STR2 //it will concatenate str1 and str2.

What does ## mean in macro?

The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.

What is a Stringize operator?

Stringizing operator (#) The number-sign or "stringizing" operator (#) converts macro parameters to string literals without expanding the parameter definition. It's used only with macros that take arguments.

What is Stringify in C++?

“Stringification” means turning a code fragment into a string constant whose contents are the text for the code fragment. For example, stringifying foo (z) results in “foo (z)” . In the C & C++ preprocessor, stringification is an option available when macro arguments are substituted into the macro definition.


2 Answers

You'll want to use the preprocessor's 'stringizing' operator, #, and probably the 'token pasting' operator, '##':

#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)

#define PRINTTHIS(text) \
    NSLog(PASTE( @, STRINGIFY(text)));

I'm not sure if Objective-C requires the '@' to have no whitespace between it and the opening quote - if whitespace is permitted, drop the PASTE() operation.

Note that you'll need the goofy 2 levels of indirection for STRINGIFY() and PASTE() to work properly with macro parameters. And it pretty much never hurts unless you're doing something very unusual (where you don't want macro parameters expanded), so it's pretty standard to use these operators in that fashion.

like image 103
Michael Burr Avatar answered Sep 22 '22 14:09

Michael Burr


Here's one way to write a macro that sticks its argument textually into a string object, though it strikes me as a bit gnarly:

#define PRINTTHIS(text) NSLog((NSString *)CFSTR(#text))

It uses the stringizing operator to turn the argument into a C string, which it then uses to create a CFString, which is toll-free bridged with NSString.

like image 29
Chuck Avatar answered Sep 22 '22 14:09

Chuck