开发者

C++ behaviour when const

开发者 https://www.devze.com 2023-01-28 14:51 出处:网络
Here\'s a basic struct (I hope) struct SomeType { float a; float b; float c; float开发者_如何学JAVA d;

Here's a basic struct (I hope)

struct SomeType {
    float a;
    float b;
    float c;
    float开发者_如何学JAVA d;

    SomeType(float, float, float, float);
};

And source

SomeType::SomeType(float na, float nb, float nc, float nd) : a(na), b(nb), c(nc), d(nd) {}

The I have a class

struct SomeClass {
    static const SomeType v;

    SomeClass();
};

When I then initialise it

const SomeType SomeClass::v(0,0,0,0);

My vales become inf or nan or -nan. Anyone seen this before, or know how to fix it?

Edit: Fixed type

Edit: This is quite close to my original example. I multiple classes with similar structure to SomeClass.


const SomeClass::v(0,0,0,0);

won't compile, since you didn't specify the type of v.

Otherwise, this works for me (and should work).

Perhaps you should post a complete, compilable example in one code listing, so we can see what you really had in mind.


From what code are you seeing those incorrect values? If it's from something like a constructor of another global variable, remember the static initialization order fiasco; v's constructor might just not have run yet.

Put an output statement in the SomeType constructor and check whether the output occurs before you see the incorrect values.


Working version:

#include <iostream>


struct SomeType {
    float a;
    float b;
    float c;
    float d;

    SomeType(float, float, float, float);

public:

    void print() const
    {
        std::cout << this->a << std::endl;
        std::cout << this->b << std::endl;
        std::cout << this->c << std::endl;
        std::cout << this->d << std::endl;
    }
};

SomeType::SomeType(float na, float nb, float nc, float nd) : a(na), b(nb), c(nc), d(nd) {}

class SomeClass {
    static const SomeType v;

    SomeClass() {}

public:

    static void print()
    {
        v.print();
    }
};

const SomeType SomeClass::v(0.0f,0.0f,0.0f,0.0f);

void main()
{
    SomeClass::print();
}

Output will be: 0 0 0 0


Though I didn’t reproduce that exact behavior, the initialization doesn’t specify the type. It should be:

const SomeType SomeClass::v(0, 0, 0, 0);

After doing this, it works fine.


Another guy told you were the problem is (static initialization order fiasco). I'll provide you with one solution. You need to get rid of the constructor, so the type will become a POD

struct SomeType {
    float a;
    float b;
    float c;
    float d;
};

Then you need to initialize it with a braced initializer list that only contains constant expressions (this is not limited to only integral constant expressions)

const SomeType SomeClass::v = { 0, 0, 0, 0 };

Alternatively, but only in the case of zeros, you can leave off the explicit values and just use empty braces

const SomeType SomeClass::v = { };

In such cases, C++ guarantees you that the values are initialized before any of your code that tries to read it runs.


Since SomeType SomeClass::v is static do you really need to explicitly initialize the members of SomeType to zero?

You can avoid the initializing Ctor of SomeType if you are only using it for initializing the members of SomeType to zero (otherwise define the default Ctor SomeType) and just initialize the static member as const SomeType SomeClass::v;.

0

精彩评论

暂无评论...
验证码 换一张
取 消