[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Strange crash in __objc_resolve_class_links
From: |
David Chisnall |
Subject: |
Re: Strange crash in __objc_resolve_class_links |
Date: |
Wed, 16 Feb 2011 14:52:58 +0000 |
On 16 Feb 2011, at 13:21, Ivan Vučica wrote:
> On Wed, Feb 16, 2011 at 13:22, David Chisnall <theraven@sucs.org> wrote:
>
>> One of the core points in the Objective-C philosophy is that there should be
>> a direct correspondence between syntax and semantics. New semantics should
>> always involve new syntax, old syntax should not be used for new semantics.
>> This is very important because it makes it easy to understand what a piece
>> of code is doing, without having to reference lots of other pieces of code.
>>
> A good philosophy. Considering that, it might have been wise for Apple to
> pick another syntax, and I tend to agree with you, Richard and other
> developers in favor of dropping the dot syntax.
Yes, and talking to people at Apple, the majority of them concur. The dot
syntax was a mistake, and some other separator would have been preferred (even
.. would have been fine).
> However, for the sake of discussion (and to defend my own decision to keep on
> using dot syntax :-) I will provide a few more arguments.
>
>
>> Contrast this with C++, for example in this line:
>>
>> doSomething();
>>
>> In C++, this can be:
>>
>> - A C function call.
>> - A static C++ member function (semantically equivalent to a C function)
>> - A non-virtual C++ member function, with this as a hidden parameter
>> - A virtual C++ member function, dynamically looked up depending on the type
>> of the callee
>>
>> In contrast, this line in Objective-C, the equivalents are:
>>
>> doSomething();
>> [MyClass doSomething];
>> [self doSomething];
>>
>> All of these are distinguishable without looking at any other code. You can
>> read this and immediately understand the semantics. This is very important
>> for readability.
>>
> While much cleaner than C++, Objective-C 1.0 does have a similar example:
> [NSString stringWithFormat:@"x %d", 5];
> [someString stringByAppendingString:@"something"];
>
> ObjC syntax does not differentiate between calls to + and - methods.
> someString might also be a class. You have to look up if it is or if it isn't
> an instance as opposed to a class method.
True, however you know it is a message send to something that is dynamically
defined (i.e. stored in a mutable pointer). Therefore, you don't know the
exact method that will be called, while you do in the former case (although
categories mean that you don't always know the exact method implementation that
will be called, you do know the path that the lookup will take).
>> Contrast this now with the dot syntax:
>>
>> a.foo;
>>
>> This can be:
>>
>> - A structure member reference
>>
> Just as you have to look up whether a symbol is a class or an instance, here
> you have to look up if it's a struct or an object.
Except that classes in Objective-C ARE objects, while structures are not. If
you use a class where you were expecting an object, stuff just works. If you
use a structure where you expect an object, things go badly wrong.
>> - An Objective-C message send calling a synthesised method that access a
>> property
>> - An Objective-C message send that calls a user-written method that may have
>> complex side effects
>>
> Solution is the very discussion we're having, and spreading information to
> warn developers about possible consequences. Aside from dropping dot-syntax,
> another possible suggestion could be that user-provided methods should be
> carefully written, weighing whether or not to add complex behavior.
Yes, if the dot notation had been properly considered then it would have
enforced these additional requirements:
- Accessor methods supplied for properties must not have side effects
- Accessor methods supplied for properties must always return the value
provided for the last set operation.
- Only methods declared with @property may be called with the dot notation
If they had made these requirements, then the dot notation would have added
something of value to the language. At present, it is semantically equivalent
to a message send and may be used interchangeably with a message send. Since
it is semantically equivalent, it does not provide any more information to the
reader or to the compiler, it just does something that looks like a field
access (which is one of the fastest operations in C) and actually makes it into
a message send or two (which are an order of magnitude slower), making it hard
to reason about the behaviour of the code.
>> This can be made much worse by things like:
>>
>> a.foo++;
>>
>> This is equivalent to:
>>
>> [a setFoo: [a foo]+1];
>>
> I disagree that this is a downside :-)
Exactly. Consider reading the two cases. In the latter, it is obvious that
you are doing two message sends and an increment. The naming conventions make
it clear that these are probably (but not necessarily) simple accessor methods.
In the former case, these observations are also true, but they are not obvious.
It's only clear that it's two message sends when you think about how the dot
notation is implemented. It's strongly implied that these are accessor
methods, but the dot notation can be used call any method, so it's not aways
the case.
>> But the syntax completely hides the fact that you're doing two method calls.
>> It lets you write code that is very complex, but with this complexity
>> completely hidden in the source. This is particularly dangerous with atomic
>> properties, because you'd intuitively assume that ++ on an atomic property
>> is an atomic operation, but it isn't.
>
> I really think that this is a minor issue and that extra brackets in such
> short statements do not contribute to readability of code. Most often, one
> will not write code that will depend on atomicity of the operation. I don't
> write multithreading code because I don't want to worry about atomicity,
> locking, race conditions, et cetera.
Then I hope you never have to write any code that is CPU dependent, since
current trends are towards lots of slower cores.
> I do not argue that everyone must use the dot-syntax, I just don't see that
> it is such a major problem. It is a nice convenience that can be quite useful
> to experienced developers. I do see the dangers of dot-syntax in the hands of
> beginners; I've worked enough with kids and grownups to see what kind of
> troubles they have, and indeed it could be an issue.
It is not just dangerous for beginners, it is a syntactic addition without a
corresponding addition. It adds another way of writing the same thing. The
only pseudoadvantage is brevity. This is the same argument that can be made in
favour of Smalltalk's -at:put:, instead of OpenStep's -setObject:forKey: and
-replaceObjectAtIndex:withObject:. The former is definitely less to type, but
if you are spending more time typing than thinking while programming, then you
are Doing It Wrong™. Most code is read more times than it is written -
especially open source code - and a second saved in typing can easily translate
to a minute or more spent understanding the code.
> But whenever I use dot-syntax, I am very conscious of what I'm doing; I am
> conscious that I am making a method call (or two!) and it's not an issue.
> And, after all, large majority of my properties are synthesized. What harm in
> using that?
You are thinking about yourself, not about the people reading your code. This
is the fastest path to unmaintainable code that I have encountered. I can
point to places in GNUstep and other projects where people have had the same
philosophy. These people have subsequently moved on to other projects, and no
one wants to touch the code.
> Finally, let me restate that I do see what bothers you, and I do agree with
> your stance a bit more. I do not, however, consider that we should call the
> dot-syntax deprecated, or avoid it when writing applications.
If I don't have to read your code, then you can do whatever you want. In
GNUstep, we don't use this syntax for exactly the same reason that we use
descriptive method names, explanatory comments, and so on - it's an open source
project and other people have to read the code.
David
--
This email complies with ISO 3103
- Strange crash in __objc_resolve_class_links, Ivan Vučica, 2011/02/15
- Re: Strange crash in __objc_resolve_class_links, Jason Felice, 2011/02/15
- Re: Strange crash in __objc_resolve_class_links, Richard Frith-Macdonald, 2011/02/16
- Re: Strange crash in __objc_resolve_class_links, Ivan Vučica, 2011/02/16
- Re: Strange crash in __objc_resolve_class_links, Nicola Pero, 2011/02/16
- Re: Strange crash in __objc_resolve_class_links, Richard Frith-Macdonald, 2011/02/16
- Re: Strange crash in __objc_resolve_class_links, David Chisnall, 2011/02/16
- Re: Strange crash in __objc_resolve_class_links, Ivan Vučica, 2011/02/16
- Re: Strange crash in __objc_resolve_class_links,
David Chisnall <=
- Re: Strange crash in __objc_resolve_class_links, Dr. H. Nikolaus Schaller, 2011/02/16
- Re: Strange crash in __objc_resolve_class_links, Ivan Vučica, 2011/02/16