7

I've heard that objective-C is a proper superset of C, but is objective-C 2.0?

The reason I ask is that either it isn't, or I misunderstand the phrase 'proper superset', because this code is valid C syntax:

#import <stdio.h>

int main () {
    char *nil = "hello";
    printf("%s\n",nil);
}

But does not compile in Objective-C 2.0. Obviously, this is an easily fixable problem, but I'm writing a paper, and feel that this is something that should be pointed out.

TylerH
  • 20,799
  • 66
  • 75
  • 101
RankWeis
  • 782
  • 2
  • 10
  • 29
  • 3
    The reason why it doesn't compile, even though you haven't included any Objective-C framework or runtime headers, is because your project probably has a precompiled header which *does* include the Foundation framework headers (and, the header which defines `nil`). – dreamlax Jun 03 '10 at 07:20
  • 1
    It does compile for me, with gcc 4.4 and the command-line `gcc some_file.m -o some_file`. So while there may be valid C programs that aren't valid Objective-C, this isn't one. – Matthew Flaschen Jun 03 '10 at 07:25
  • [This question](http://stackoverflow.com/q/9941842/166749) points out a more poignant counterexample to the "strict superset" myth: any C program that uses `id` as an identifier will fail to compile as Obj-C. – Fred Foo Sep 04 '14 at 12:34

2 Answers2

15

nil is not a keyword. nil is defined in objc.h [on Mac OS X] (and __DARWIN_NULL is really just NULL):

#ifndef nil
#define nil __DARWIN_NULL   /* id of Nil instance */
#endif

That is, nil isn't really part of the compiled language, but a convention used during compilation that is perpetuated by the system libraries.

Splitting hairs, obviously. You really could compile Objective-C source without nil, though.

It is akin to asking "Can I write a tool that has variables named deflate while still using the zlib.h interface?". Sure. But it'll be ugly.

And, in fact, the compiler does not automatically include objc.h. This:

#include <stdio.h>

int main() {
    int nil = 5;
    fprintf(stdout, "Hello %d\n", nil);
    return 0;
}

Compiles and runs just fine in a standard Foundation tool project (in the main.m) once you remove the precompiled/prefix header that imports Foundation and, hence, objc.h. (So, yes, out of the box, the Xcode templates do cause objc.h to be imported by way of importing Cocoa/Cocoa.h or Foundation/Foundation.h.)

bbum
  • 162,346
  • 23
  • 271
  • 359
  • So you're saying that XCode, when it compiles my code, gives the compiler some options which causes nil to be defined? Because I did notice where it was defined, but I just assumed it was part of the modifications that Apple had made to the GNU C compiler... – RankWeis Jun 03 '10 at 07:02
  • 1
    The question is not whether you "could compile Objective-C source without nil". It's whether you can compile valid C that uses nil as Objective-C. – Matthew Flaschen Jun 03 '10 at 07:06
  • Follow the includes... somewhere something `#included `; Foundation, AppKit, Cocoa, something. IIRC, it isn't automatically included by the compiler (I *might* be wrong-- Objective-C without `objc.h` isn't something I've given much consideration). – bbum Jun 03 '10 at 07:08
  • @Matthew You could. But it would be a complete pain in the ass because you wouldn't be able to follow the standard patterns of Objective-C *and the standard runtime or system libraries*. But, again, this isn't a language issue... it is a library issue. – bbum Jun 03 '10 at 07:09
  • If the compiler automatically includes it, then I would say it is a language issue. And being a strict superset means it's up to the programmer if and how much he wants to follow Objective-C patterns. – Matthew Flaschen Jun 03 '10 at 07:11
  • 2
    The compiler doesn't automatically include it. – bbum Jun 03 '10 at 07:16
  • You're right, @bbum. I think dreamlax's suggestion may be the issue. – Matthew Flaschen Jun 03 '10 at 07:27
3

Objective-C a proper superset of C, as everything that works in C will work with Objective-C.

BUT,

as it is a superset, it adds some new types, definitions and directives.

That means that if you use a reserved definition like nil, you are getting into serious trouble.

That's why the above program does not compile.

Community
  • 1
  • 1
Laurent Etiemble
  • 27,111
  • 5
  • 56
  • 81
  • +1 - I know this comment is late (this is an old post), but your answer is what I was thinking. If it is a *proper superset* it adds things not present in the subset. That means that code written for the subset language could be interpreted differently in the superset language and even throw errors because you used a reserved word as a variable name. – Adam Jones Sep 16 '11 at 23:49
  • Adding new types, definitions or directives, if doing so makes any previously valid program break or change its semantics, would make objective-c *no longer* a superset. Unless, of course, you have to do something impossible in valid C to enable them before. – Deduplicator Jan 05 '16 at 17:14