Objective-C: & ldquo; Hello world & rdquo; COMPILED! without Foundation headers. Why?

advertisements

Consider the following code:

//#import <Foundation/Foundation.h>

int main(int argc, const char *argv[]) {
    @autoreleasepool {
        NSLog(@"Hello World!");
    }
    return 0;
}

I cannot understand why it could be built and run? w/out Foundation header!

For me it is still strange that C compiler COMPILES this code w/out header i.e. w/out DECLARATIONS. It's strange that compiler matches my function somehow to already compiled code (Foundation) and succeeds. Are there some links to C standard that will explain me how compiler resolves token that recognized as a function and was never previously declared?

Please, explain!!

UPDATE: These if not due to pre-compiled headers

Thank you! But NO. I tested it the following way - just typed Hello World code in vi editor and saved it as main.m file. Than compiled it with clang from Terminal. And e-thing went Okay with 1 warning only:

main.m:8:9: warning: implicitly declaring library function 'NSLog' with type 'void (id, ...)' NSLog(@"Hello World!");
^ main.m:8:9: note: please include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLog'
1 warning generated.

UPDATE: Just attaching all the images step-by-step:


There's no reason it shouldn't compile. As you're seeing, without that header present, the compiler is assuming NSLog is a function with signature void NSLog(id, ...). In this case, you're even luckier, because that signature happens to be compatible with the real function declaration - meaning your program will actually even work correctly as well:

FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);

Note that without linking against Foundation, the build won't succeed:

$ make example
cc     example.m   -o example
example.m:3:9: warning: implicitly declaring library function 'NSLog' with type
      'void (id, ...)'
        NSLog(@"Hello World!");
        ^
example.m:3:9: note: please include the header <Foundation/NSObjCRuntime.h> or
      explicitly provide a declaration for 'NSLog'
1 warning generated.
Undefined symbols for architecture x86_64:
  "_NSLog", referenced from:
      _main in example-943cd4.o
  "___CFConstantStringClassReference", referenced from:
      CFString in example-943cd4.o
  "_objc_autoreleasePoolPop", referenced from:
      _main in example-943cd4.o
  "_objc_autoreleasePoolPush", referenced from:
      _main in example-943cd4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [example] Error 1

You need to add -framework Foundation:

$ CFLAGS="-framework Foundation" make example
cc -framework Foundation    example.m   -o example
example.m:3:9: warning: implicitly declaring library function 'NSLog' with type
      'void (id, ...)'
        NSLog(@"Hello World!");
        ^
example.m:3:9: note: please include the header <Foundation/NSObjCRuntime.h> or
      explicitly provide a declaration for 'NSLog'
1 warning generated.