0

I've been working on a couple established C++ projects that use static variables from a shared library to store parameters. When compiled with g++ or clang++, the static variable is shared (has the same memory location) throughout the entire program. However, when compiled with Xcode, the main function static variable has a different memory location than the shared library static variable. Is there a way to get Xcode to compile/run the code the same as g++ or clang++, while still being able to debug with Xcode?

Please see example below:

main.cpp:

#include <iostream>
#include "Params.hpp"

int main(int argc, const char * argv[]) {
    Params param = Params();
    param.addParams();
    std::vector<int> vi = Params::ParamsObj();
    vi.push_back(10);
    for(std::vector<int>::iterator it = vi.begin(); it != vi.end(); ++it) {
            std::cout << "i = " << *it << std::endl;
    }
    return 0;
}

Params.hpp:

#ifndef Params_hpp
#define Params_hpp

#include <vector>

class Params{
    typedef std::vector<int> ParamVector;
public:
    static ParamVector& ParamsObj() {
        static ParamVector m;
        return m;
    }
    void addParams();
};

#endif /* Params_hpp */

Params.cpp:

#include "Params.hpp"

void Params::addParams(){
    Params::ParamsObj().push_back(5);
}

Makefile:

clang:
    clang++ -dynamiclib Params.cpp -o libshared_clang.dylib
    clang++ main.cpp -o main_clang ./libshared_clang.dylib

gpp:
    g++-mp-4.9 -Wall -shared -fPIC -o libshared_gpp.so Params.cpp
    g++-mp-4.9 -Wall -o main_gpp main.cpp ./libshared_gpp.so  

Output from both g++ and clang++ is:

i = 5
i = 10

While Xcode only outputs i = 10.

If I don't use a shared library and compile everything into one binary, Xcode will properly output both print statements.

My current solution is to add the project's main function into its own shared library and then create an Xcode specific file which merely calls the main function in the newly created shared library. However, I was hoping for a solution that didn't require changing the underlying project's code.

1 Answer 1

1

I'm pretty sure that if you turn on optimalization for gcc/clang (which you did not in your example), they will produce the same behavior as your compilation with XCode (which isn't a compiler, but an IDE).

Your problem is that the ParamsObj() function is inline (defining it in the class body adds an implicit inline keyword to it), allowing the compiler to just "paste" it into the main method instead of calling it.

With dll boundaries, this might result in the allocation of multiple static variables, if the function is used in multiple libraries (in your case, it's used in the dll, and inlined into the main executable).

Refactor the ParamsObj() method into a declaration and a separate definition in the corresponding C++ file, and you'll get the same behavior everywhere, printing both numbers.

Sign up to request clarification or add additional context in comments.

3 Comments

Adding optimization (-O3 or -O2) doesn't change any of the behavior. Also, as I mentioned in the question, the code I'm working with is a part of large established projects, so I would prefer to not have to refactor the parameters object for those projects. I do understand that Xcode is an IDE, but (from what I understand) it does use it's own compiler, which is what I was trying to refer to.
Refactoring only means moving one method's implementation into another file, I don't think it's a big change if it fixes the problem. Or you could try adding __attribute__((noinline)) to the function, if XCode's compiler supports it. Even if it works currently, nothing guarantees that this kind of code will work on all platforms.
Thank you for the help. Moving the ParamsObj() method as you suggested did fix the problem. Alternatively, while __attribute__((noinline)) doesn't work with Xcode, __attribute__((visibility("default"))) does work and is simpler than rearranging the code. I also found that "Inline Methods Hidden" can be set in the Xcode "Build Settings" to get a similar effect. I found this page useful when looking into this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.