cxcodecompiler-errorsduplicate-symbol

Why is this not a duplicate symbol error?


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.


Solution

  • 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)