views:

687

answers:

3

I'm looking at some open source projects and I'm seeing the following:

NSLog(@"%s w=%f, h=%f", #size, size.width, size.height)

What exactly is the meaning of '#' right before the size symbol? Is that some kind of prefix for C strings?

+4  A: 

Is this the body of a macro definition? Then the # could be used to stringize the following identifier i.e. to print "string" (without the codes).

dirkgently
+7  A: 

To elaborate on dirkgently's answer, this looks like the implementation of a macro that takes an NSSize (or similar) argument, and prints the name of the variable (which is what the # is doing; converting the name of the variable to a string containing the name of the variable) and then its values. So in:

NSSize fooSize = NSMakeSize(2, 3);
MACRO_NAME_HERE(fooSize);

the macro would expand to:

NSLog(@"%s w=%f h=%f", "fooSize", fooSize.width, fooSize.height);

and print:

fooSize w=2.0 h=3.0

(similar to NSStringFromSize, but with the variable name)

smorgan
+1  A: 

The official name of # is the stringizing operator. It takes its argument and surrounds it in quotes to make a C string constant, escaping any embedded quotes or backslashes as necessary. It is only allowed inside the definition of a macro -- it is not allowed in regular code. For example:

// This is not legal C
const char *str = #test

// This is ok
#define STRINGIZE(x) #x
const char *str1 = STRINGIZE(test);      // equivalent to str1 = "test";
const char *str2 = STRINGIZE(test2"a\"");  // equivalent to str2 = "test2\"a\\\"";

A related preprocessor operator is the token-pasting operator ##. It takes two tokens and pastes them together to get one token. Like the stringizing operator, it is only allowed in macro definitions, not in regular code.

// This is not legal C
int foobar = 3;
int x = foo ## bar;

// This is ok
#define TOKENPASTE(x, y) x ## y
int foobar = 3;
int x = TOKENPASTE(foo, bar);  // equivalent to x = foobar;
Adam Rosenfield