I always get a build error when I try to define a C function in the header file just above the interface of the class.
but when I do the same in the implementation file
This is to do with the way that the C linker (or link editor) works. When the C compiler comes across a function definition, it prepares the assembler code that implements that function and marks it with a symbol that says to the linker "this is where the function with this name starts". The symbol is usually named with an underscore followed by the function name, e.g. _printf
.
If you define the function in a header file, then every .c
or .m
file that imports this header will compile the function, and will cause the compiler to emit the same symbol. The linker expects to only find one instance of each symbol, so this is an error.
This is unrelated to the existence of #include
guards, or to using #import
instead of #include
. The C compiler works on individual translation units - by which it means individual source files. Preprocessor strategies stop you including the same header file twice into a single source file, but do nothing to coordinate activities across multiple files. That means that it's valid to include the same headers in different source files: it also means that when you compile different files, they can (legitimately) contain the same symbol.
It's the job of the link editor to put these files together, resolving any references to symbols that were unknown at compilation time. If you try to link objects (the name of compiled and assembled translation units) that have the same symbol into the same archive, shared library or executable, then you'll get the error you're seeing here.
Solutions:
inline
. Inline functions are just copied by the compiler into the function where they're called, so a linker symbol is never emitted for them. This has its own trade-offs that you may wish to read more about.