3

I have a hyerarchy of classes. Methods of these classes may create temporary static arrays of the same size. I want to set size as static const field of the base class.

I put declaration of the field in a heared file and initialized it in a source file. This works without issues when compiled using GCC 4.3 but fails with VS compiler.

Base.h

class Base
{
public:
    virtual void function();

protected:
    static const int size;
};

Base.cpp

#include "Base.h"

const int Base::size = 128;

void Base::function()
{
    int array[size];
}

Derived.h

#include "Base.h"

class Derived : public Base
{
    void function();
};

Derived.cpp

#include "Derived.h"

void Derived::function()
{
    int array[size];
}

Main.cpp

#include "Derived.h"

int main()
{
    Base* object = new Derived();
    object->function();
    return 0;
}

I expected that size would be initialized in Base.cpp and considered as const in Derived.cpp. But it works only with GCC compiler. Visual Studio shows the following error messages:

error C2131: expression did not evaluate to a constant

note: failure was caused by non-constant arguments or reference to a non-constant symbol

note: see usage of 'size'

3
  • I don't think it should work, since when compile Derived::function, size is still unknown (any maybe even impossible to determine in compile time). (although I'm not sure what the standard say) Commented Jan 27, 2019 at 13:19
  • does this have something to do with variable length array? Commented Jan 27, 2019 at 13:22
  • 3
    GCC has a VLA extension which is why it works. You should make size constexpr and initialize it in Base declaration. Commented Jan 27, 2019 at 13:29

2 Answers 2

3

A constant variable can only be used in a constant expression after its initialisation has been encountered (and is a constant initialiser). Base::size hasn't been initialised in Derived.cpp, so it cannot be used in a constant expression (such as length of the array): The program is ill-formed.

How to use static const field of a base class as size of an array in functions of a derived class?

Initialise the size within the class declaration, and declare it constexpr.

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

Comments

1

As pointed out in the comments, a GCC extension makes this compile successfully. The problem is easily fixable by removing

const int Base::size = 128;

And change the Base::size (in .h) to

static constexpr int Base::size = 128;

This makes sure Base::size can be evaluated at compile-time. If you want to be have more influence on the value of size, templates can be used:

template <int N>
class Base {
    protected: static constexpr int size = N;
};

called through

Base<10>::size; // returns 10
Base<128>::size; // returns 128

using my_base = Base<128>;
my_base::size; // returns 128

Comments

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.