title: Symbols not found when compiling for C++, but found for C
body: <p>I'm trying to compile some code on OS X under C++, but I'm running into some symbol not found issues. </p>
  
  <p>When I compile for C, it works just fine:</p>
  
  <pre><code>g++ -x c -fobjc-arc -fobjc-link-runtime -framework IOKit -framework CoreFoundation -framework Foundation kextstat/main.cpp -o ks
  </code></pre>
  
  <p>When I change <code>-x c</code> to <code>-x c++</code>, suddenly symbols aren't found:</p>
  
  <pre><code>$ g++ -x c++ -fobjc-arc -fobjc-link-runtime -framework IOKit -framework CoreFoundation -framework Foundation kextstat/main.cpp -o ks
  Undefined symbols for architecture x86_64:
    "OSKextCopyLoadedKextInfo(__CFArray const*, __CFArray const*)", referenced from:
        _main in main-66ed7f.o
    "kas_info(int, void*, unsigned long*)", referenced from:
        print_kextstat(__CFDictionary const*) in main-66ed7f.o
  ld: symbol(s) not found for architecture x86_64
  clang: error: linker command failed with exit code 1 (use -v to see invocation)
  </code></pre>
  
  <p>I stripped out the references to those symbols and got the C++ version to compile so that I could check out the libraries that each binary was linking against to see if there was an inconsistency, but they were exactly the same:</p>
  
  <pre><code>$ otool -L ks_cxx
  ks_cxx:
      /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
      /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.17.0)
      /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1056.13.0)
      /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
      /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
      /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
  $ otool -L ks_c
  ks_c:
      /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
      /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.17.0)
      /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1056.13.0)
      /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
      /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
  </code></pre>
  
  <p>Here's a code listing of <code>main.cpp</code>:</p>
  
  <pre><code>#import &lt;CoreFoundation/CoreFoundation.h&gt;
  
  #define KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR (0)
  #define KAS_INFO_MAX_SELECTOR (1)
  int kas_info(int selector, void *value, size_t *size);
  extern CFDictionaryRef OSKextCopyLoadedKextInfo(CFArrayRef, CFArrayRef);
  
  // Convert a CFString to a standard C string
  char* cstring(CFStringRef s) {
    return ((char*)CFStringGetCStringPtr(s, kCFStringEncodingMacRoman));
  }
  
  void print_kextstat(CFDictionaryRef dict) {
    size_t kaslr_size = 0;
    uint64_t kaslr_slide = 0;
    kaslr_size = sizeof(kaslr_slide);
    int ret = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &amp;kaslr_slide, &amp;kaslr_size);
    if (ret != 0) {
      printf("[ERROR] Could not get kernel ASLR slide info from kas_info(). Errno: %d\n", errno);
      exit(1);
    }
    printf("[INFO] Kernel ASLR slide is 0x%llx\n", kaslr_slide);
  
    CFIndex count = CFDictionaryGetCount(dict);
    CFIndex i, j;
  
    void **keys;
    void **values;
  
    keys = (void **)malloc(sizeof(void *) * count);
    values = (void **)malloc(sizeof(void *) * count);
  
    CFDictionaryGetKeysAndValues(
      dict,
      (const void **)keys,
      (const void **)values
    );
  
    printf("Index Refs Address            Size         Wired        Name (Version) &lt;Linked Against&gt;\n");
    for (i = 0; i &lt; count; i++) {
      for (j = 0; j &lt; count; j++) {
        int kextTag;
        int refs;
        unsigned long long address;
        unsigned long long size;
        unsigned long long wired;
  
        char *name = cstring((CFStringRef)CFDictionaryGetValue((CFDictionaryRef)(values)[j], CFSTR("CFBundleIdentifier")));
  
        CFNumberGetValue(
          (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j], CFSTR("OSBundleLoadTag")),
          kCFNumberSInt32Type,
          &amp;kextTag
        );
        if (kextTag != i) {
          continue;
        }
        CFNumberGetValue(
          (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j], CFSTR("OSBundleRetainCount")),
          kCFNumberSInt32Type,
          &amp;refs
        );
        CFNumberGetValue(
          (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j], CFSTR("OSBundleLoadAddress")),
          kCFNumberSInt64Type,
          &amp;address
        );
        CFNumberGetValue(
          (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j], CFSTR("OSBundleLoadSize")),
          kCFNumberSInt64Type,
          &amp;size
        );
        CFNumberGetValue(
          (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j], CFSTR("OSBundleWiredSize")),
          kCFNumberSInt64Type,
          &amp;wired
        );
        printf("%5d %4d 0x%-16llx 0x%-10llx 0x%-10llx %s (%s) ",
          kextTag,
          refs,
          address + kaslr_slide,
          size,
          wired,
          name,
          cstring((CFStringRef)CFDictionaryGetValue((CFDictionaryRef)values[j], CFSTR("CFBundleVersion")))
        );
  
        CFArrayRef linkedAgainst = (CFArrayRef)CFDictionaryGetValue(
          (CFDictionaryRef)values[j],
          CFSTR("OSBundleDependencies")
        );
  
        if (linkedAgainst == NULL) {
          printf("\n");
          continue;
        }
  
        CFIndex linkedCount = CFArrayGetCount(linkedAgainst);
        int linked = 0;
  
        CFMutableArrayRef marray = CFArrayCreateMutableCopy(
          NULL,
          linkedCount,
          linkedAgainst
        );
  
        CFArraySortValues(
          marray,
          CFRangeMake(0, linkedCount),
          (CFComparatorFunction)CFNumberCompare,
          NULL
        );
  
        printf("&lt;");
        int l;
        for (l = 0; l &lt; linkedCount; l++) {
          CFNumberGetValue(
            (CFNumberRef)CFArrayGetValueAtIndex(marray, l),
            kCFNumberSInt32Type,
            &amp;linked
          );
  
          if (l)  {
            printf(" ");
          }
          printf ("%d", linked);
        }
        printf("&gt;\n");
      }
    }
  }
  
  int main (int argc, char **argv) {
      if (getuid() != 0) {
          printf("[ERROR] Please run me as root!\n");
          exit(1);
      }
  
      print_kextstat(OSKextCopyLoadedKextInfo(NULL, NULL));
  }
  </code></pre>