0

[OSX 10.12.6, LLVM Clang ++ 9.0]

I need to convert a library written in C++11 (which uses initialisation lists) to C++03 form (or earlier). The library is a header only implementation of a 3D model. In the library, I have a struct that contains a number of properties which themselves are custom classes.

struct BodyPoint {
    BodyPoints          name;
    Point3D<double>     orientation;
    Point3D<double>     offset;

    BodyPoint() {}
    BodyPoint(BodyPoints _name, Point3D<double> _orientation, Point3D<double> _offset):
    name(_name), orientation(_orientation), offset(_offset) {}
};

1) BodyPoints is a typedef enum BodyPoints that enumerates points of interest on the object I'm controlling. (declared in this library)
2) The Point3D<double> (included from another header)

The library provides a pre-defined array of BodyPoints which is global to the modules that use it.

So, after the declaration of the struct, I am declaring an array variable. However, I'm getting an error declaration requires a global constructor [-Werror,-Wglobal-constructors]

My array declaration is as follows:

static BodyPoint bodyPoints[2] =
{
  BodyPoint(bWorld,Point3D<double>(0.0,0.0,0.0), Point3D<double>(0.00,0.00,0.00) ),
  BodyPoint(bHead, Point3D<double>(0.0,0.0,0.0), Point3D<double>(0.00,0.00,0.00) )
};

How do I create a constructor for an array of structs and where in my code would I do that? (Also, I don't want to use vectors here.)

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
gone
  • 1,079
  • 5
  • 13
  • 31
  • Can you provide a reproducible [mcve]? It compiles with add some missing pieces [here](http://coliru.stacked-crooked.com/a/d288282f7f936948) – NathanOliver Oct 02 '17 at 13:42
  • Read Howard Hinnant's answer here: https://stackoverflow.com/questions/15708411/how-to-deal-with-global-constructor-warning-in-clang – Chris Uzdavinis Oct 02 '17 at 14:13
  • @NathanOliver: Thanks, and it's not what I expected. The only diff in my code is that main, BodyPoint, and Point3D are in separate files and I'm using XCode 9's version of Clang++. The command includes flags: `-fblocks -O2 -std=c++11 -stdlib=libc++ -Werror -Weverything -Wno-unknown-pragmas -Wno-weak-vtables -Wno-padded -Wno-unused-variable -Wno-unknown-warning-option -Wno-reserved-id-macro` *(which incidentally sets C++11, not 98)*. [Our build sets those flags, including C++11, but in the end I need to code to conform to C++03 or earlier standard for cross compilation reasons.] – gone Oct 02 '17 at 14:26
  • @ChrisUzdavinis: I've looked at that example already, and whilst I don't understand how the solution using the class reference and the constructor body should be implemented, it doesn't look to apply in my case as I'm using a struct and an array. I don't want to add any more properties to the struct, nor do I want to wrap it into a parent class. – gone Oct 02 '17 at 14:29
  • @gone It looks like the warning is because you have a global object. If you are going to have global arrays you should just turn the warning off. Or you could use implement your own `std::array` and use Howard's work around. – NathanOliver Oct 02 '17 at 14:31
  • The first part of Howard's technique that I don't understand has to do with the my_A() { ... } function. I'm unclear as to whether that's a member function of `class A` or he's defining a new function that declares a local static instance of A and returns a reference to it. Then, how do you reference the A&? I don't want to introduce another layer of variables when accessing the bodyPoints array; I need to be able to use `bodyPoints[1].offset = Point3D – gone Oct 02 '17 at 14:43

1 Answers1

1

The warning doesn't mean you have to add a global constructor, it means that you are declaring global variable(s) that require constructor calls while initializing the globals. The compiler is just warning that they are running in that context, before main(), before the whole program is initialized.

It's not a problem per se, though order of global initialization can be problematic with cross translation-unit dependencies, and they can slow down your program's startup.

You can disable the warning -Wno-global-constructors.

Another suggestion made was to make a function that returns static local data.

Chris Uzdavinis
  • 6,022
  • 9
  • 16
  • As per my 3rd comment above. The initialisation of the local data structure would be performed in the body of the function? An another problem is that I would then need to call that function to get the reference. – gone Oct 02 '17 at 14:48
  • If you make a function that returns static local data, then yes. Only on the first call. But while that is lazy (if you don't use it, you don't construct it) it also means that it may be constructed at an inconvenient time. Lazy construction is always like that, though in this case it's probably not that big of a deal. – Chris Uzdavinis Oct 02 '17 at 17:14