views:

280

answers:

4

What you can't do in C (C99 standard) that you can do in Objective-C? (with code example if you please)

+1  A: 

There isn't such a thing. Generally, you can program anything in any programming language.

Sjoerd
As long as "anything" leaves out a lot of things.
danben
@Sjoerd: Fantastic, can you post your solution to the Halting Problem please. http://en.wikipedia.org/wiki/Halting_problem
JeremyP
really Sjoerd? guess we only need one programming language then! /sarcasm
Jage
+1 since it is what is already said in other answers, without sarcasm and without posing Halting problem. Contextualizing (always necessary) makes the assertion simply true.(We live in a limited world and computers are made by humans)
ShinTakezou
+8  A: 

Absolutely nothing. Objective-C's OO features are implemented as a small runtime library written in C.

While some commenters might point out that Objective-C has blocks and C doesn't, that's actually a GCC/LLVM extension to C that Objective-C makes use of, it's not an ObjC feature.

Graham Lee
A feature that it is often worth avoiding the use of, since it sometimes requires an executable stack (gcc generates a trampoline on the stack to restore the stack frame so that scope nesting works, a trampoline is a small function that does some magic :P)An executable stack may not be available... for example with NX turned on (gcc probably uses madvise or something so it will still work... maybe)
Spudd86
To add to Graham's well-made points, the small runtime library is even exposed as a set of C functions that you're allowed to use. In other words, you can even use Objective-C libraries without using Objective-C. See here: http://developer.apple.com/mac/library/documentation/cocoa/reference/objcruntimeref/Reference/reference.html
harms
Blocks -- as implemented in Mac OS X -- absolutely do *not* require an executable stack. That was a requirement in their design.
bbum
Using the runtime library doesn't allow anything like the object-oriented coding you can do in Objective-C. You can create the same data structures and call the same functions, but it's like the difference between hugging someone and building a robot to hug them for you.
Chuck
@Chuck -- using the runtime library you can compose classes on the fly, do inheritance, do method dispatch (with inheritance), etc... You really could do fully OO programming in nothing but C. It would, in fact, be a complete PITA.
bbum
@bbum the point is that you can do OO programming without a language that "supports" OO syntax at all, ok. You can do OO programming directly in assembly if you want. But... fast enumeration is useful, and being a syntax construct not allowed in C, it is something C can't do while Objective-C can.
ShinTakezou
(prevent an objection: NSEnumerator instead of for/in ... then while instead of for(a;b;c) ... then goto and labels only... again on the first point: you can OO without syntax support by the lang, but it is not the same, and the reason why "abstractions" exist disappear)
ShinTakezou
+3  A: 

As Graham said -- there is absolutely nothing that can be done in Objective-C that can't be done in C. Of course, there isn't anything you can do in C, either, that can't be done in assembly. It is just a matter of typing.

(I was hoping that the the assembly mention would be enough to indicate that, no, I'm not remotely suggesting that writing OO patterns in pure C is remotely a productive thing to do...)

There are a few additional points of interest:

  • Objective-C started out as a preprocessor that turned Objective-C code into C code that could be compiled by a standard C compiler. That is, Objective-C was originally never directly compiled, but translated to straight C, then compiled.

  • Objective-C objects can be thought of as C structures where the first entry in the structure -- the isa -- is always a pointer to the metadata -- the Class -- that describes the structure/instance.

  • Blocks are an extension to C, now proposed as an addition to the C language in WG-14 (C standards committee). Blocks, as implemented by Apple, absolutely do not require an executable stack. It was a hard requirement in their design.

  • LLVM has a rewriter that can actually rewrite Objective-C to C and has, apparently, been used to enable Objective-C coding in Xbox 360 games (see http://permalink.gmane.org/gmane.comp.compilers.llvm.devel/31996).

bbum
not a matter of typing only. HL syntaxes and different paradigms help "thinking differently", and change the perception of a problem (and so change the way you find the solution). They are tools and without them you can't reach the same high. You can't think that to build a cathedral it is enough to know how to put bricks over bricks and to use the same tools you used to build your 1meter tall first brick-house.If you start re-typing,you'll find soon you're re-building/writing those tools you already had...but once you do it,you're confirming you need them to go on.cycle
ShinTakezou
@ShinTakezou I believe you and I are in violent agreement. I never meant to imply that writing OO code in straight C was a reasonable solution.
bbum
+4  A: 

I'm going to be a little bit presumptuous and disagree with everyone else. While it's technically true that anything possible in one language is possible in another (where "possible" means "computable"), they differ in what you can express naturally and easily. The computer might be doing the same thing in response to the code you write in C, but you are writing radically different code to make it do those things.

As others have said, Objective-C provides a full runtime library written in C that will allow you to create Objective-C data structures and call C functions, but the code to do it will be very verbose, fairly roundabout and completely imperative. In Objective-C, the code is more declarative, more concise and far more readable.

In general, trying to write Objective-C things in C will only make your code worse than it would be using either language idiomatically. For example, here is a simple program written in Objective-C:

@interface NumberAdder : NSObject {
    int storedValue;
}

- (id)initWithStoredValue:(int)value;
- (int)resultOfAddingStoredValue:(int)numberToAdd;
@end

@implementation NumberAdder
- (int)resultOfAddingStoredValue:(int)numberToAdd {
    return numberToAdd + storedValue;
}

- (id)initWithStoredValue:(int)value {
    if (!(self = [super init])) return nil;
    storedValue = value;
    return self;
}
@end

int main() {
    id adder = [[NumberAdder alloc] initWithStoredValue:4];
    int result = [adder resultOfAddingStoredValue:3];
    printf("It is %d\n", result);
    return 0;
}

And here is the same thing written in C with the Objective-C runtime (not tested, but should be roughly correct):

int returnPlusStoredValueImp(id self, SEL _cmd, int arg) {
    int *storedValue = nil;
    object_getInstanceVariable(self, "storedValue", &storedValue)
    return arg + *storedValue;
}

id numberAdderInit(id self, SEL _cmd, int valueToStore) {
    objc_super superInfo = {self, objc_lookupClass("NSObject")};
    self = objc_msgSendSuper(super_info, sel_getName("init"));
    if (!self) return nil;
    object_setInstanceVariable(self, "storedValue", &valueToStore);
    return self;
}

void createNumberAdderClass() __attribute(constructor)__ {
    Class NumberAdder = objc_allocateClassPair(objc_lookupClass("NSObject"), "NumberAdder", 0);
    if (!NumberAdder) return;
    class_addIvar(NumberAdder, "storedValue", sizeof(int), 4, "i"); // I'm actually not sure if the fourth argument is correct, so it's probably wrong, but just take that as a sign of how much this way of coding sucks
    objc_registerClassPair(NumberAdder);
    SEL nameOfPlusStoredValue = sel_registerName("resultOfAddingStoredValue:");
    SEL nameOfInit = sel_registerName("initWithStoredValue:");
    class_addMethod(NumberAdder, nameOfPlusStoredValue, returnPlusStoredValueImp, "i@:i");
    class_addMethod(NumberAdder, nameOfInit, numberAdderInit, "@@:i");
}

int main() {
    id adder = objc_msgSend(objc_lookupClass("NumberAdder"), sel_getName"alloc");
    adder = objc_msgSend(adder, sel_getName("initWithStoredValue:"), 4);
    int result = (int)objc_msgSend(adder, sel_getName("resultOfAddingStoredValue:"), 3);
    printf("It is %d\n", result);
    return 0;
}
Chuck
+1 for taking the hard line and demonstrating it. Nice answer.
bbum
virtually +2, since the whole point around computer languages is this (or around), since otherwise we all would use still assembly, since no need for higher "linguistic structures" would arise.
ShinTakezou