Problem with Initialisation of global objects to my class.

My class works for local assignment and use, but setting a global array gives a zero value.

My example program should output 3 copies of the same {0,1,0} value but my global 'c' is all zeros.

Do I need to assign it at run time?

I have an assignment defined in my class
eg
Rgb& operator=(Rgb& that);
Rgb& operator=(const Rgb& that);


$ cat main.cpp

#include <stdio.h>
#include <GL/glut.h>

#include "rgb.h"

using namespace std;

const int i[3] = {2,4,6};
const Rgb c[3] = { Rgb::colRed, Rgb::colGreen, Rgb::colYellow };

int main( int argc, char **argv) {

Rgb l = Rgb::colGreen;

cout << i[1] << l << c[1] << Rgb::colGreen << endl;

return 0;
}

$ ./main
4{0, 1, 0}{0, 0, 0}{0, 1, 0}

Last edited on
Looks like the static initialization order fiasco.

If you define two static variables in different translation units (.cpp files) you can not be sure in what order they will be initialized. For you it looks like c is initialized before Rgb::colGreen.

https://isocpp.org/wiki/faq/ctors#static-init-order
Last edited on
Is RGB a class ? Is RBG::colRed , etc enums ?

If so , you cannot use the assignment operator in your class because you need to assign another instance of the same class .

But I would like to see the RGB.h please.
// this is my rgb.h file.
// note the GL bits come from openGL glut library
//
// the colours are all defined in rgb.cpp like this.
// const Rgb Rgb::colGreen(0,1.0,0) ;

#pragma once
#ifndef ONCE_RGB
#define ONCE_RGB

#include <iostream>
#include <GL/glut.h>

using namespace std;

class Rgb
{
public:
Rgb();
Rgb(GLfloat r, GLfloat g, GLfloat b);
~Rgb(void);

Rgb(Rgb& that );
Rgb(const Rgb& that );
Rgb& operator=(Rgb& that);
Rgb& operator=(const Rgb& that);

bool operator==( Rgb &rhs ) ;
bool operator==( const Rgb &rhs ) const ;

Rgb operator*=(double that);
Rgb operator/=(double that);
Rgb operator+=(Rgb that ) ;

void glcolour( ) const;

friend ostream& operator<<(ostream& output, const Rgb& p);

GLfloat fRed;
GLfloat fGreen;
GLfloat fBlue;

static const Rgb colWhite;
static const Rgb colRed;
static const Rgb colGreen;
static const Rgb colBlue;
static const Rgb colMagenta;
static const Rgb colCyan;
static const Rgb colYellow;
static const Rgb colMidGray;
static const Rgb colDarkGray;
static const Rgb colLightGray;
static const Rgb colBlack;

};

#endif
Last edited on
Tried using an instance of Rgb, but still is not initialized.

e.g

Rgb zero( 0, 0, 0 );
Rgb c[3] = { zero.colRed, zero.colGreen, zero.colYellow };
It doesn't matter if you access the static objects through an instance or through the class name. It's still the same objects so it gives you the same result.
Last edited on
I think Peter8u7 is right. To test this, try moving const Rgb c[3] = { Rgb::colRed, Rgb::colGreen, Rgb::colYellow }; inside main() to force it to initialize after static/global data. If this is indeed the problem then change Rgb::colred etc to be constexpr.
normally a static const member attribute is initialized in the class definition.

like that :

static const int NUM = 5;

except probably for const pointers , but I never put them const . If a static member is not const , then it must be initialized outside the class scope (like in a cpp file).

The thing is that it is not a primitive type and it is a RGB so the compiler tries to look at the class definition but it was not defined yet since the compiler did not see the }; My advise would be to remove the static and initialize them all in the list initializer since they are const.

Thanks, I think I understand the limitation.

I can initialise my global in the start of main()

This will work in the openGL program I am writing, I just assumed I was doing it wrong.
Now I know global initialization needs to be done in main.


....
int main( int argc, char **argv) {

Rgb c[3] = { zero.colRed, zero.colGreen, zero.colYellow };
for( int x=0; x<3; ++x ) d[x] = c[x];
....
Now I know global initialization needs to be done in main.

It doesn't need to be done in main(). The problem is what Peter87 pointed out: If you have two globals in two different C++ files then you don't know which one gets initialized first. This means that if one is initialized from the value of the other, then the results are undefined:
file1.cpp:
int a = 9;
file2.cpp:
1
2
extern int a;
int b = a;


Here b is initialized from a, but it's possible that b is initialized before a, so it might get zero, or (unlikely) some other value.
But the random order means you have to fix it in some constant way, like in the main.
So what other ways can you make the order fixed?

try to remove Gl\Glut.h from the main.cpp
Topic archived. No new replies allowed.