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;


And GFloat.h is :

#import "Generic.h"

@interface GFloat : Generic {

	float value;

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

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.


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 […]


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 )

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s

%d bloggers like this: