1

I have a c++ program in which constants are stored within a class. And somewhere else in the code I use one of these constants as an array size.

Here is a sample:

Constants.h

#ifndef CONSTANTS_H
#define CONSTANTS_H

class Constants
{
public:
    static const unsigned int C_BufferSize;
};

#endif

Constants.cpp

#include "Constants.h"

const unsigned int Constants::C_BufferSize(128);

main.cpp

#include "Constants.h"

int main()
{
    char buffer[Constants::C_BufferSize];
    return 0;
}

When I compile this code with -std=c++11 -pedantic I got the following warning:

main.cpp:5:37: warning: ISO C++ forbids variable length array ‘buffer’ [-Wvla]

I don't really understand the error since the size is a constant, my guess is that at compile time the size is unknown.

The error can be bypassed using a heap allocated table (allocated with new), but I'm forbidden to use dynamic memory allocation. Therefore I'm looking for another solution.

4
  • #define C_BUFSIZE 128 or whatnot. Commented Jan 15, 2014 at 12:28
  • @BЈовић Biggest assertion ever. Commented Jan 15, 2014 at 12:30
  • You could use an enum, or C++11 initializer ({128}), and I think you could even intialize in-class (= 128). Commented Jan 15, 2014 at 13:01
  • Unless you wanted to use said constant in an #if condition. Commented Jan 15, 2014 at 13:11

2 Answers 2

1

The definition is required and searched for, at link-time. So yes, the size is unknown during the compilation phase.

You're write this:

class Constants
{
public:
    static const unsigned int C_BufferSize = 128; //initialize here
};

And then only provide the definition in .cpp file:

const unsigned int Constants::C_BufferSize; //no initialization here

But then it makes better sense to make Constants a namespace instead of a class:

namespace Constants  //NOTE : a namespace now
{
    static const unsigned int BufferSize = 128; 
};

Seems more natural to me.

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

2 Comments

After a few tests it seems that the definition in cpp file is not mandatory.
@Mika it is if you odr-use it by e.g. taking its address. If you take its address but don't define it in a .cpp file you should get a linker error (this is for a static data member, not a global).
0

Warning reason - as mentioned by @nawaz already (variable size in array at compile time - might not be supported/allowed by all compilers).

can be attempted this way instead:

std::vector<char> buffer(Constants::C_BufferSize);

Typically the above issue would arise when doing some char* conversion to string (limited by actual data size in the char-buffer). Therefore in that case, this can be used something like;

std::string ConvertCharDataBySizeToString(const char* s, std::size_t size)
{
    std::vector<char> data(s, s+size);
    return ( std::string(data.begin(), data.end()) );
}

Reference/s here.

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.