The second line solicits the error:
1>E:\WX\wx_numbers_01\base_58_verify_class.h(69,37): error C2327: 'base_58_verify_class::max_length': is not a type name, static, or enumerator (compiling source file top_panel.cpp)
Why is a simple constant forbidden in a simple array declaration?
Size_t is a narrow name for an unsigned int. “const unsigned int” tells the compiler, where an unsigned is appropriate and the name of the constant is found, put the value there. The scope is defined by the limitations of the class in which it is declared. It should only be valid within the scope of the class and when an object of the class is instantiated. There is no need for the constant to be valid outside of the scope of the and/or when no object of said class is instantiated.
So why does this need to be static?
And it is not an expression. The number 257, or another other specific number, not calculated, is not an expression. It is just a number.
And even if calculated such as:
Const int x_size = 10; const int y_size = 20; const area = x_size * y_size;
It can and should be calculated at compile time and never again. “constexpr” is not needed.
Time to change my perspective. A question about this declaration
1 2 3 4 5 6 7 8
class my_class
{
private:
const size_t max_1 = 256;
char str_1[ max_length ]; // error
staticconst size_t max_2 = 256
char str_2[ max_2 ]; // this is ok
}
Question: What advantage is accrued by adding the word static?
But something else is strange. I noticed that in an h file, not within a class, are these lines:
1 2 3 4 5 6 7 8 9 10
const size_t test_array_count = 5;
const size_t test_array_max_length = 50;
constchar base_58_text[ test_array_count ][ test_array_max_length ] =
{
"1",
"A",
"alpha",
"Hello World",
"Works well for a long string."
};
The phrase static is not there, but the compiler does not complain.
This strikes me as being inconsistent. What am I missing?
This strikes me as being inconsistent. What am I missing?
The difference between member variable and global variable.
An array size requires a global constant that exists throughout the lifetime of the program. A member variable does not fulfill this and hence the array size could not be determined at compile time.
Amazing as it may seem, a member const variable can have it's value set at run-time. As the size of an array has to be be known at compile time, a const member variable can't be used for an array size!
The only requirement is that the array bound (the number of elements in the array) must be a constant expression;
and its value should be greater than zero.
Anything is allowed, as long as this requirement is met.
(Constant expressions are expressions that can be evaluated at compile time. http://eel.is/c++draft/expr.const )
The answers have covered too much ground and I am not able to recognize the essence of my question. Presume an h file contains this:
class one
{
const int name_max = 64;
char name[ name_max ];
// more class code.
};
When an object of this class is created the name array is set to 64 characters. If another object of this class is created, or N objects created, each one has a char array "name" that is 64 characters is size.
name_max is not a compile-time constant. Each object would have its own name_max variable. 64 is just the default value.
Constructors could initialize it to a different value.
1 2 3 4 5 6 7
class one
{
private:
constint name_max = 64;
public:
one(int n) : name_max(n) {}
};
Or if one is an "aggregate class" (only public member variables, no user-provided constructors, etc.) then you could specify a value when initializing the object.
1 2 3 4 5 6 7 8
class one
{
public:
constint name_max = 64;
};
one x; // x.name_max is equal to 64
one y{20}; // y.name_max is equal to 20
So that is why name_max is not considered to be a compile-time constant.
Consider replacing VS 2019 with VS 2022, or if you have the space both can be installed side-by-side. VS 2022 requires a 64-bit CPU to run, though it can still compile for 32-bit.
Not that it matters in this instance 2022 is more likely to be updated for C++23.
VS 2019 is fully C++20 as is 2022 if that is of any concern.
VS 2022 gobbles up less HD space for the same installed packages, is a bit less CPU intensive and marginally less buggy. In my experience 2019's C++20 implementation, especially using custom created modules, can have compile-time issues. Intellisense can really goes loopy in 2019.
name_max is not a compile-time constant. Each object would have its own name_max variable. 64 is just the default value.
I cannot see it that way. The declaration is: constint name_max = 64;
That says: Compiler! Every time you see the variable named name_max, it SHALL have the value 64! Do not ever allow name_max to contain or represent ANY other value.
Peter87: example code instantiated a class with the line: one y{20}
I do not see how that changed the value of the constant. The constructor does not have an argument. I do not see anything that directs the value 20 to the declared constant name_max.
GeorgeP: You pushed me over the edge, purchase of VS 2022 is in progress.
I cannot see it that way. The declaration is: constint name_max = 64;
That says: Compiler! Every time you see the variable named name_max, it SHALL have the value 64! Do not ever allow name_max to contain or represent ANY other value.
That's what it means if you write it inside a function or in global/namespace scope but not if you write it as a non-static member of a class. Context matters.
example code instantiated a class with the line: one y{20}
I do not see how that changed the value of the constant. The constructor does not have an argument. I do not see anything that directs the value 20 to the declared constant name_max.
Do you know what a struct is? Then you perhaps know that you can specify the values for the member variables this way. If you do not declare a constructor and make all member variables public then you can do the same with classes.
Note that the value of the const member variable didn't change. It was simply initialized to that value when it was created.
Technically structs and classes are the same thing. The only difference is that struct use public by default while class use private by default. Everything you can do with a struct you can do with a class and vice versa.
That says: Compiler! Every time you see the variable named name_max, it SHALL have the value 64! Do not ever allow name_max to contain or represent ANY other value.
NO!! Not as a variable definition within a class. To have that meaning you also need to define as static. That's the way the C++ language is defined. Accept what the language means and move on. You've been told this several times now.
Regarding VS 2022, BitDefender declares the msbuild.exe a threat and won't let it run. Found a thread about that a few months old and the problem has not been corrected. Back to VS 2019.