2

Apple uses the following code in the header of all its framework classes.

#if !defined(__COREFOUNDATION_CFARRAY__)
#define __COREFOUNDATION_CFARRAY__ 1
...
#endif

Is this a recommended approach for eliminating "duplicate symbol" linker errors, when designing classes or categories for framework use, or are these left over protection from the use of #include instead of #import in c?

Research into this has lead me to this article on include guard

NOTE: this question is not asking how to fix a duplicate symbol error, but instead asking if there is any way of preventing your own code from causing the problem if its included more than once in a project.

Andrew
  • 462
  • 5
  • 15

2 Answers2

3

You're right about the include guard - there's probably some compatibility reason it's not been removed from the source.

However, this won't really protect you against duplicate symbols much.

For example,

What if you have two third party library, each of which uses the SBJSON library (I had this happen to a colleague a few weeks ago).

Each of the libraries was compiled seperately so, from their point of view, SBJSON was only included once. However, when I came to link my app I couldn't because I had duplicate symbols.

I had to solve this by manually removing the symbols from one of the .a library files (This link shows it's quite a common problem!)

EDIT : This link is a much clearer step by step solution to the problem

deanWombourne
  • 38,189
  • 13
  • 98
  • 110
  • I have also had it happen with SBJSON in two separate frameworks. Is there nothing that can be done (including any sort of runtime manipulation)? – Andrew Sep 05 '12 at 09:33
  • You can fix it before compilation (scroll down in the link in my answer and there's a few solutions) but you can't fix it at runtime if it won't compile :) – deanWombourne Sep 05 '12 at 09:41
  • @Andrew - check out my second link for a better set of instructions :) – deanWombourne Sep 05 '12 at 09:43
  • Thanks for that. I previously fixed a similar category framework problem by removing the all_load linker flag in Xcode. Here i'm actually asking if there is any way of preventing the issue from occurring in the first place? I'm guessing the answer is no if the source is compiled at separate times. – Andrew Sep 05 '12 at 09:48
  • 1
    You're right, the answer is no. We just have to hope that the original library builders haven't included other libraries directly :( And removing `all_load` has other side effects that might cause objects to have missing methods at runtime (e.g. if a category on an object contains methods that aren't directly called then the linker won't include that category unless `all_load` is passed as a flag. However, some other code might try to call those methods dynamically and cause a crash because they're missing :) – deanWombourne Sep 05 '12 at 09:56
  • 2
    Alternatively you can define an empty class using a macro before the category implementation: http://latest.docs.nimbuskit.info/Preprocessor-Macros.html#gNI_FIX_CATEGORY_BUG to avoid using all_load or force_load – Andrew Sep 05 '12 at 10:02
  • @Andrew - that's a nice trick, I like that :) Every day's a school day! – deanWombourne Sep 05 '12 at 10:05
1

Apple uses the following code in the header of all its framework classes.

Not necessarily for the ObjC APIs. But CoreFoundation, yes they use include guards. It's still idiomatic in many camps to use traditional #includes in C sources, and to use #import for objc sources (#import is a compiler extension, not traditional C).

Is this a recommended approach for eliminating "duplicate symbol" linker errors

No, it does not prevent linker errors; it can result in duplicate declaration errors during compile phases.

If you're getting duplicate symbol linker errors, the problem is something else, such as visibility of definition. For that, you should provide an example of your troubling program.

justin
  • 104,054
  • 14
  • 179
  • 226