3

I have an instance variable which is a struct, for example:

struct Data {
    UInt32 i;
    UInt32 arr[1];
};

And a property is defined in my class:

@property struct Data data; // and the corresponding @synthesize in the imp file

Now, I am aware that changing the values of i and arr through the getter of data is conceptually wrong, since I will be accessing the copy of data returned by the getter (the correct way is accessing it using self->data).

However some general Objective-C questions arise regarding the following lines:

self.data.i = 1;      // produces compile error        
self.data.arr[0] = 1; // compiles ok

First, why does the first line produces a compile error, and the 2nd line does not?

Second, if the dot syntax in the above line (self.data) is just a syntactic sugar to [self data], why do I get 2 different (although similar) compile errors?

self.data.i = 1;   // error: Expression is not assignable
[self data].i = 1; // error: Semantic Issue: Assigning to 'readonly' return result of an objective-c message not allowed
1
  • 1
    This is the same reason self.frame.size = CGSizeMake(320,460) doesn't work. Commented Jan 28, 2012 at 10:47

1 Answer 1

5

Actually, structs are passed by value in C (and Objective C). That means that your property actually returns a read only copy (rvalue) of the internal "Data" type. The assignment is to the temporary returned copy, which the compiler (rightfully) flags as a bit suspect.

The second line that compiles correctly does so since self.data.arr returns a read only UInt32*, but when you index it with [0] and write to that, you're not writing to the pointer, you're writing to the memory that it points to which is allowed.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes, this is clear from the error message, but how come the 2nd line compiles ok?
@ItamarKatz Missed that part, added some info clarifying that to the answer.
@ItamarKatz The second statement compiles and works because self.data.arr returns a pointer to a C array, an element of which you then modify. In other words, you're not modifying the internal struct's fields.
Thanks, it's clear now. Coming form c++, it's like the difference between a const int * and int * const

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.