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.