views:

1104

answers:

13

I have just begun learning Objective-C, coming from a VB .Net and C# .Net background. I understand pointer usage, but in Objective-C examples I see the asterisk placed in several different places, and search as I might, I have not been able to find an answer as to why this is. Every search I try turns up all kinds of explanations about pointers (which I really don't need), but not a single mention of the reasons/effects of the different placements of the asterisk. Here are some examples I've seen:

NSString *string;
NSString * string;
(NSString *) string;
NSString* string;

(I had to put a line between each because the preview here was misrepresenting what I was typing.)

What do these different positions of the asterisk mean? I'm sure it's a simple answer but it's frustrating not being able to find it in any of the Apple tutorial and reference documentation or online so far.

Can someone please end my misery and answer this perplexing question? Thanks!

A: 

there actually all equivalent: a pointer to an nsstring!!

ennuikiller
+10  A: 

There is no difference — it's a matter of style. They all declare a variable called string that's a pointer to an NSString. The parentheses are necessary in some contexts (particularly method declarations) in order to clarify that it's a type declaration.

Chuck
I think you mean there's no difference in spacing around the asterisk, but as others have pointed out, the 3rd line is (by itself) a cast to an NSString* (which one might use if string is an `id` of CFStringRef) or possibly part of an Objective-C method declaration. To me, at least, your meaning was clear.
Quinn Taylor
I nevertheless prefer the last form (coming from a C++ background): it demarcates clearly the type and the object. Here is a nice little discussion about this topic by Stroustrup: http://www.research.att.com/~bs/bs_faq2.html#whitespace
Nocturne
+7  A: 
1.  NSString *string;
2.  NSString * string;
3.  (NSString *) string;
4.  NSString* string;

1, 2 and 4 are exactly identical. It's all style. Pick whatever you want, or mix it up.

Choice #3 has another meaning also, it's used in casting. For example:

t = (NSString *)string ;

will cast string to an NSString pointer.

But choice #3 is the syntax you'd probably use in a .h file or in the function definition in a .m file. Inside an actual function, in code which is "run" it has a different meaning.

marcc
Although it's a valid typecast, there should never be a need to explicitly cast an object to NSString* -- if you're downcasting from id or void*, you can do the cast implicitly, and if you're upcasting from a subclass (such as NSMutableString), you can also do so implicitly.
Adam Rosenfield
+1, but statement 3 is actually a nop - you'd likely not want to use that line anywhere. You would use it as part of an expresion to cast the `string` to an NSString*, but it's not valid as a declaration. Of course, I'm not familiar with Objective-C, so if there's a use for statement 3 in that dialect of C, please let me know that I'm spouting nonsense, and I'll delete this comment.
Michael Burr
Agreed. And thanks, good point. But syntactically, it's a cast. I just wanted to point it out because there definitely will be times where the OP poster will see it.
marcc
Actually, just to clarify for Michael Burr, defining a member function in ObjC is like: - (void)doSomething:(NSString *)param1 { }This is why everyone says it's a valid declaration, because it is, in this situation.
marcc
There is a need to explicitly cast to NSString if you start with an NSObject and cast to a number of different types.
Kendall Helmstetter Gelner
+2  A: 

it doesn't matter where you put your asterisk, all statements create pointers of type NSString.

when using multiple variable names in one line you have to write the asterisk for each variable though.

NSString * nsstring, * nsstring2;
knittl
... which is one of the ugliest things in C and should therefore be avoided.
Nikolai Ruhe
A: 

1, 2 and 4 are equivalent and define a pointer to an NSString. My personal preference is to emulate K&R as much as possible, so I like to use NSString *string;

(NString*)string; though a valid statement, doesn't really do anything by itself.

$ cat foo.m
#include <Cocoa/Cocoa.h>

void foo()
{
    NSString *string;

    (NSString*) string;  // doesn't do anything
    42;   // doesn't do anything either
}

$ gcc -Wall -c foo.m
foo.m: In function 'foo':
foo.m:7: warning: statement with no effect
foo.m:8: warning: statement with no effect
sigjuice
+1  A: 
1.  NSString *string;
2.  NSString * string;
3.  (NSString *) string;
4.  NSString* string;

1,2 and 4 are equivalent. The C language (and the Objective-C superset of C) specify a syntax that is insensitive to white space. So you can freely add spaces where you choose as a matter of style. All relevant syntax is delimited by non-whitespace characters (e.g. {, }, ;, etc.) [1].

3 is either a type cast (telling the C compiler to use the NSString* type regardless of the declared type of string. In Objective-C, type casting of object instances is rarely necessary. You can use the id type for variables that can reference instances of any object type.

In method declarations, syntax 3 (sometimes without the ending semicolon) is used to declare the type of method parameters. An Objective-C method may look like this:

- (void)myMethodThatTakesAString:(NSString*)string;

In this declaration, the type of the argument named string is type NSString* (the leading - indicates an instance method as oppose to a class method). A method declaration with more than one parameter might look like this:

- (void)myMethodTakingAString:(NSString*)string andAnInteger:(NSInteger)intParam;

[1] This is compared to languages like Python which use whitespace as a block delimeter.

Barry Wark
+3  A: 

There is no difference, where the * is placed in a pointer declaration is irrelevant.

John Millikin
+2  A: 

There is absolutely no difference between these.

coneybeare
+2  A: 

No difference, whitespace placement is irrelevant.

JStriedl
+5  A: 

no, there is no difference. btw, this is an exact duplicate of this question: http://stackoverflow.com/questions/1105815/placement-of-the-asterisk-in-objective-c/1105868#1105868

knittl
+11  A: 

There is no difference, however you should be aware that only the first "token" (so to speak) defines the type name, and the * is not part of the type name. That is to say:

NSString *aString, bString;

Creates one pointer-to-NSString, and one NSString. To get both to be pointers, do either:

NSString *aString, *bString;

or:

NSString *aString;
NSString *bString;
dcrosta
Since the original question was about placement of `*`, I edited your answer slightly to reduce confusion.
John Millikin
…and of course you can't declare an NSString variable that is not a pointer (outside of POC dialect), so the first code example would not compile.
Chuck
+2  A: 

There is absolutely no difference. NSString* mystring and NSString *myString are identical.

Daryl
+1  A: 

the * works the same way as it does in standard C.

this is a nice primer on putting the * in different places and what it does: http://boredzo.org/pointers/

pxl