I have a iOS framework that contains .c
, .mm
source files.
For convenience let's call these two files A.c
and B.mm
.
In both files, I defined a function with the same function protocol like the following.
// A.c
uint32_t get_file(const char *path)
{
...
}
// B.mm
uint32_t get_file(const char *path)
{
...
}
As far as I know, I thought this would throw an error at compile time because there's duplicate symbol, but it successfully compiles the framework without any error. What am I missing here?
Note:
This will be a duplicate symbol
linker error if it was .c
and .m
because Objective-C doesn't undergo name mangling.
Objective-C++ files (.mm) are C++ files, so they undergo name mangling. If you run nm
on the output, you'll see something along the lines of:
$ nm a.out | grep get_file
0000000100000fa0 T __Z8get_filePKc
0000000100000f70 T _get_file
If you applied extern "C"
in the C++ version to remove name mangling, you'd see the collision you're expecting:
// B.mm
extern "C" uint32_t get_file(const char *path)
{
return 0;
}
$ clang A.c B.mm
duplicate symbol _get_file in:
/var/folders/j3/32xftcp56c12hqz7y8rl4f600000gn/T/A-d00e10.o
/var/folders/j3/32xftcp56c12hqz7y8rl4f600000gn/T/B-d853af.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)