54

So, I saw this:

error:(NSError **)error

in the apple doc's. Why two stars? What is the significance?

Swanand Pangam
  • 858
  • 1
  • 10
  • 25
Allyn
  • 20,271
  • 16
  • 57
  • 68

5 Answers5

70

A "double star" is a pointer to a pointer. So NSError ** is a pointer to a pointer to an object of type NSError. It basically allows you to return an error object from the function. You can create a pointer to an NSError object in your function (call it *myError), and then do something like this:

*error = myError;

to "return" that error to the caller.


In reply to a comment posted below:

You can't simply use an NSError * because in C, function parameters are passed by value—that is, the values are copied when passed to a function. To illustrate, consider this snippet of C code:

void f(int x)
{
    x = 4;
}

void g(void)
{
    int y = 10;
    f(y);
    printf("%d\n", y);    // Will output "10"
}

The reassignment of x in f() does not affect the argument's value outside of f() (in g(), for example).

Likewise, when a pointer is passed into a function, its value is copied, and re-assigning will not affect the value outside of the function.

void f(int *x)
{
    x = 10;
}

void g(void)
{
    int y = 10;
    int *z = &y;
    printf("%p\n", z);    // Will print the value of z, which is the address of y
    f(z);
    printf("%p\n", z);    // The value of z has not changed!
}

Of course, we know that we can change the value of what z points to fairly easily:

void f(int *x)
{
    *x = 20;
}

void g(void)
{
    int y = 10;
    int *z = &y;
    printf("%d\n", y);    // Will print "10"
    f(z);
    printf("%d\n", y);    // Will print "20"
}

So it stands to reason that, to change the value of what an NSError * points to, we also have to pass a pointer to the pointer.

mipadi
  • 398,885
  • 90
  • 523
  • 479
  • hi, am little late here. Would like to ask: why must we pass a pointer to a pointer to NSError or in general in order to return an object? For example from the above, if we only pass a pointer to an object, would this suffice: error = myError? (Speaks: error is a pointer to my new error object myError)? Hope you can further explain the justification of using a double pointer. Thanks very much in advance. – Unheilig Jan 08 '14 at 02:52
  • @Unheilig: I updated my answer with a reply to your question. – mipadi Jan 08 '14 at 09:14
  • Thanks for the write-up, but you meant `int f(int **x)` in your last example, right? And if so, should this - `printf("%d\n", y);` - also be changed to: `printf("%d\n", &y);` (added `&` to `y`) in the `void` method instead of `y` as well? – Unheilig Jan 08 '14 at 14:57
  • Also, I think there is a problem in code from the 2nd example with incompatible types namely in the method `void f(int*)` when you do `x = 10` (needs dereferenced `*`). Thanks. – Unheilig Jan 08 '14 at 15:57
  • 1
    @Unheilig: The sample is correct, although perhaps a bit confusing, but I was demonstrating that you need a pointer to your base data type in order to change the value. In the case of an `int`, this is an `int *`; following the same logic, in the case of `NSError *` being your base data type, it's `NSError **`. – mipadi Jan 09 '14 at 04:04
45

In C everything is pass by value. If you want to change the value of something you pass the address of it (which passes the value of the memory address). If you want to change where a pointer points you pass the the addres of the pointer.

Take a look here for a simple explanation.

TofuBeer
  • 60,850
  • 18
  • 118
  • 163
10

In C, a double star is a pointer to a pointer. There are a couple of reasons to do this. First is that the pointer might be to an array of pointers. Another reason would be to pass a pointer to a function, where the function modifies the pointer (similar to an "out" parameter in other languages).

geofftnz
  • 9,954
  • 2
  • 42
  • 50
7

The double star (**) notation is not specific to initializing a variable in a class. It is simply a double indirect reference to an object.

float myFloat; // an object
float *myFloatPtr; // a pointer to an object
float **myFloatPtrPtr; // a pointer to a pointer to an object
        
myFloat = 123.456; // initialize an object
myFloatPtr = &myFloat; // initialize a pointer to an object
myFloatPtrPtr = myFloatPtr; // initialize a pointer to a pointer to an object
        
myFloat; // refer to an object
*myFloatPtr; // refer to an object through a pointer
**myFloatPtrPtr; // refer to an object through a pointer to a pointer
*myFloatPtrPtr; // refer to the value of the pointer to the object

Double pointer notation is used where the caller intends that one of its own pointers need to be modified by a function call, so the address of the pointer, instead of the address of the object, is passed to the function.

An example might be the use of a linked list. The caller maintains a pointer to the first node. The caller invokes functions to search, add, and remove. If those operations involve adding or deleting the first node, then the caller's pointer has to change, not the .next pointer in any of the nodes, and you need the address of the pointer to do that.

Kaz
  • 1,047
  • 8
  • 18
Kumarsunil
  • 151
  • 2
  • 7
4

If it is anything like C then ** means a pointer to a pointer.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635