Search code examples
c++macosinitializationstatic-initialization

Force variable in source file into initialized data segment on OS X?


I have a bool type in a CPP source file. The variable cannot be made static. I want the variable placed in an initialized data segment.

According to the OS X ABI Mach-O File Format Reference, I believe the place I want the variable to reside is __DATA,__data from Table 2.

How can I force a variable an initialized data segment on OS X using Apple compilers?

I realize that I'm probably going to have to use something platform specific. I also realize it won't be portable C++.


Solution

  • To force data into an initialized data segment when available on OS X and Linux (but not GNU Hurd), perform the following. Note that this technique is platform specific, but it side steps C/C++ limitations on visibility and storage classes.

    #if defined(__clang__ ) && !defined(__apple_build_version__)
       #define LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
    #elif defined(__clang__ ) && defined(__apple_build_version__)
       #define APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
    #elif defined(__GNUC__)
       #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
    #endif
    ...
    
    
    #if ((__MACH__ >= 1) && ((LLVM_CLANG_VERSION >= 30600) || (APPLE_CLANG_VERSION >= 70100) || (GCC_VERSION >= 40300)))
       #define INIT_SECTION __attribute__((section ("__DATA,__data")))
    #elif ((__ELF__ >= 1) && (GCC_VERSION >= 40300))
       #define INIT_SECTION __attribute__((section ("nocommon")))
    #else
       #define INIT_SECTION
    #endif
    

    foo.h:

    extern bool g_x;
    extern bool g_y;
    

    foo.cpp:

    bool INIT_SECTION g_x, INIT_SECTION g_y;
    

    I'm still working on the compiler version numbers, so they may not be as accurate as they could be. They tested OK under LLVM Clang, Apple Clang, GCC, and MacPorts GCC. But I suspect Clang will be able to move down, and GCC may need to move up.