Dynamic typing and returned value in Objective-C

I tried writing these code for something.

GInt.h is :

#import "Generic.h"

@interface GInt : Generic {

	int value;
}

- (void)add:(id)valObj;
- (int)value;
- (void)setData:(int)aVal;
- (NSString *)description;

@end

And GFloat.h is :

#import "Generic.h"

@interface GFloat : Generic {

	float value;
}

- (void)add:(id)valObj;
- (float)value;
- (void)setData:(float)aVal;
- (NSString *)description;
@end

Implementation for the GFloat is :

#import "GFloat.h"

@implementation GFloat
- (void)add:(id)valObj
{
	float temp_value;

        // This yields error
	temp_value = [valObj value];

	value += temp_value;
}

- (float)value
{
	return value;
}

- (void)setData:(float)aVal
{
	value = aVal;
}

in the add: message, [valObj value] returns something strange.
If value message is sent to the valObj, the Objective-C runtime successfully send the message to GFloat, and returns float value. However, in the caller’s source line, i.e. add: message, wrong value is returned.
Isn’t it strange? I confirmed that the message itself returns a correct float value. But when the program counter is back at the caller, wrong value is there!

Then, how to solve it?

	temp_value = (float)[valObj value];

Hmm.. it does not solve the problem.
Actually this solves it.

	temp_value = [(GFloat *)valObj value];

By the way, Apple’s Objective-C manual explains this way :

Return and Argument Types
In general, methods in different classes that have the same selector (the same
name) must also share the same return and argument types. This constraint is
imposed by the compiler to allow dynamic binding. Because the class of a
message receiver (and therefore class-specific details about the method it’s
asked to perform), can’t be known at compile time, the compiler must treat all
methods with the same name alike. When it prepares information on method return
and argument types for the runtime system, it creates just one method
description for each method selector.

So, the original code was wrong, because the return types of value message of GInt and GFloat are different.
However, GCC 3.4.5 of MingW doesn’t raise any error, while GCC 4.0.1 from Apple raises an error.

Let’s summarize it.

  • With dynamic typing, correct message is called.
  • With dynamic typing, an object returns wrong value. So, do not depend on it.

Be careful when accessing returned value of dynamically typed object.
I reported this issue to the GCC bug report page with bug number 26283

NOTE : In 2010~2011 time frame, Apple introduced ARC (Automatic Reference Counting) and retried the garbage collection supported by Obj-C runtime. So, ARC is your new GC.
Even in this ARC, the same problem happens. It’s discussed here.

ADDED : cf.  When calling a message of an id type fails <= This document explains more about it.

About these ads

One response to this post.

  1. [...] while ago, I posted an article saying that I found one glitch in sending message to an object. I mentioned “This is it!”, but I forgot what that was. At Telestream, one Mac developer [...]

    Reply

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 48 other followers

%d bloggers like this: