declaration of a Multidimensional array without index numbers - c++

I was wondering how it is possible to declare char arrays this way:
char szArray[]={"one"};
char szArrayTwo[][6]={{"one"},{"two"},{"three"}};
But this way doesn't work
char szArrayTwo[][]={{"one"},{"two"},{"three"}};
NOTE:
I am aware of the c++ tag even though it should be c, but it is being used in the c++ context with a c++ compiler

In fact it could be done for constant expressions used as initializers. But in this case for example for character arrays the compiler has to calculate the maximum length of string literals. And it is more difficult if an array is multidimensional.
The task will be more complicated if initializers are calculated at run time. In fact it is impossible to generate an appropriate code by the compiler.

In c++, an array with 2 dimension or more, the rightmost dimensions must always be defined.

string ArrayOne[] { "one","two","three" };
will work, and so will
char* ArrayTwo[] { "one","two","three" };
but a true multidimensional array must have at most one undefined dimension size (the leftmost)

Related

how to revise a const int value c++

I have a "expected constant expression" error.
This is my error part:
int row=counter/4;
int goals[row][4];---> this part has error for "row" variable
how to define "row" variable like a constant value? or how to solve this problem?
C++ does not allow arrays of variable size. In your example, row is not a constant, and as such, can not be used to specify array size.
To workaround this, you might either switch to C (which does allow such arrays) or use C++ constructs - such as std::vector.
Syntaxically correct change would be to rephrase row as
const size_t row = counter / 4;
But than you'd need counter const, which you would not be able to do if you are getting it from the user input.
you can use only compile time constants in array declaring.
constexpr could help you,
http://en.cppreference.com/w/cpp/language/constexpr
but not for all compilers, look for the answer here:
constexpr function as array size

Complex array initialization in c++

There is a problem when I want to define a complex array:
#include<complex.h>
int main(){
int matrix=1000;
std::complex<double> y[matrix];
}
The error is "Variable length array of non-POD element type 'std::complex'
Is there something wrong with the definition of array here?
This kind of array only works with a length that is a constant expression, i.e. the length must be known at compile time.
To get a array of variable length, use an std::vector<std::complex<double>> y (matrix);
You should use std::vector (or std::array in some cases) over C-style arrays anyway.
You can't statically allocate a C++ array with size being a regular variable, since the value of matrix is not known until the program is executed. Try dynamically allocating your array:
std::complex<double> y = new std::complex<double>[matrix]
When you are doing using it, call:
delete[] y
The size of arrays must be know at compile time. It must be a constant expression. The value of matrix is only known at runtime. You must make matrix a constant to work.
const int matrix=1000;
The other way around is to use a vector whose size is variable and is initialized at runtime.
int matrix=1000;
std::vector<std::complex<double>> y(matrix);
C++ doesn't allow variable length arrays, either do it dynamically or use a vector.
Your compiler thinks that you are declaring a variable-length array, since matrix is non-const. Just make it constant and things should work:
const int matrix = 1000;
std::complex<double> y[matrix];
The error stems from the fact that variable-length arrays are only allowed for "dumb" data types, e.g. int/char/void* and structs, but not classes like std::complex.

Expected constant in 2d array

double rainPerMonth(const int YEARS)
{
int monthYear[MONTHS][YEARS];
// ...
}
Visual Studio shows a squiggly line underneath the array declaration, saying that YEARS must be a constant when I'm creating the array. Is this an IDE issue because the variable has yet to be initialized, or am I writing this incorrectly?
MONTHS is already declared globally.
An array size must be a constant expression - that is, a value known at compile time. (Some compilers offer C-style variable-length arrays as a non-standard extension, but I don't think Visual C++ does. Even if it does, it's better not to rely on such extensions.)
A function argument isn't known at compile time, so can't be used as an array size. Your best option is here is probably
std::vector<std::array<int, MONTHS>> monthYear(YEARS);
In C++, an array must be sized at compile time. What you are attempting to do is declare one that is sized at runtime. In the function you've declared, YEARS is only constant within the scope of the function. You could call it rainPerMonth(someInt); where someInt is the result of some user input (which shows you that the result is not a compile-time constant).
Variable Length Arrays are an extension to C, but not C++. To do what you want, you can use dynamic memory, or a std::vector.
I think your problem lies in the fact that C++ wants a constant in the sense of compile-time constant to create your variable monthYear. If you pass it as a function, it need not be known at compile time? For example:
const int x=2;
const int y=3;
char xyChoice;
std::cin >> xyChoice;
if (xyChoice == 'x')
rainPerMonth(x);
else
rainPerMonth(y);
I'm unsure, but it seems to me like this would give you a constant int being passed to your function, but the compiler wouldn't know what size to create an array for before runtime?

usage of const in c++

I am new to C++.I was going through a C++ book and it says
const int i[] = { 1, 2, 3, 4 };
float f[i[3]]; // Illegal
It says the declaration of the float variable is invalid during compilation.Why is that?
Suppose if we use
int i = 3;
float f[i];
It works.
What is the problem with the first situation?
Thanks.
So the first is illegal because an array must have a compile-time known bound, and i[3], while strictly speaking known at compile time, does not fulfill the criteria the language sets for "compile-time known".
The second is also illegal for the same reason.
Both cases, however, will generally be accepted by GCC because it supports C99-style runtime-sized arrays as an extension in C++. Pass the -pedantic flag to GCC to make it complain.
Edit: The C++ standard term is "integral constant expression", and things qualifying as such are described in detail in section 5.19 of the standard. The exact rules are non-trivial and C++11 has a much wider range of things that qualify due to constexpr, but in C++98, the list of legal things is, roughly:
integer literals
simple expressions involving only constants
non-type template parameters of integral type
variables of integral type declared as const and initialized with a constant expression
Your second example doesn't work and it shouldn't work.
i must be constant. This works
const int i = 3;
float f[i];
Just to expound on Sebastian's answer:
When you create a static array, the compiler must know how much space it needs to reserve. That means the array size must be known at compile-time. In other words, it must be a literal or a constant:
const int SIZE = 3;
int arr[SIZE]; // ok
int arr[3]; // also ok
int size = 3;
int arr[size]; // Not OK
Since the value of size could be different by the time the array is created, the oompiler won't know how much space to reserve for the array. If you declare it as const, it knows the value will not change, and can reserve the proper amount of space.
If you need an array of a variable size, you will need to create it dynamically using new (and make sure to clean it up with delete when you are done with it).
For arrays with lengths known only at runtime in C++ we have std::vector<T>. For builtin arrays the size must be known at compile-time. This is also true for C++11, although the much older C99-standard already supports dynamic stack arrays. See also the accepted answer of Why doesn't C++ support dynamic arrays on the stack?

Only one array without a size allowed per struct?

I was writing a struct to describe a constant value I needed, and noticed something strange.
namespace res{
namespace font{
struct Structure{
struct Glyph{
int x, y, width, height, easement, advance;
};
int glyphCount;
unsigned char asciiMap[]; // <-- always generates an error
Glyph glyphData[]; // <-- never generates an error
};
const Structure system = {95,
{
// mapping data
},
{
// glyph spacing data
}
}; // system constructor
} // namespace font
} // namespace res
The last two members of Structure, the unsized arrays, do not stop the compiler if they are by themselves. But if they are both included in the struct's definition, it causes an error, saying the "type is incomplete"
This stops being a problem if I give the first array a size. Which isn't a problem in this case, but I'm still curious...
My question is, why can I have one unsized array in my struct, but two cause a problem?
In standard C++, you can't do this at all, although some compilers support it as an extension.
In C, every member of a struct needs to have a fixed position within the struct. This means that the last member can have an unknown size; but nothing can come after it, so there is no way to have more than one member of unknown size.
If you do take advantage of your compilers non-standard support for this hack in C++, then beware that things may go horribly wrong if any member of the struct is non-trivial. An object can only be "created" with a non-empty array at the end by allocating a block of raw memory and reinterpreting it as this type; if you do that, no constructors or destructors will be called.
You are using a non-standard microsoft extension. C11 (note: C, not C++) allows the last array in a structure to be unsized (read: a maximum of one arrays):
A Microsoft extension allows the last member of a C or C++ structure or class to be a variable-sized array. These are called unsized arrays. The unsized array at the end of the structure allows you to append a variable-sized string or other array, thus avoiding the run-time execution cost of a pointer dereference.
// unsized_arrays_in_structures1.cpp
// compile with: /c
struct PERSON {
unsigned number;
char name[]; // Unsized array
};
If you apply the sizeof operator to this structure, the ending array size is considered to be 0. The size of this structure is 2 bytes, which is the size of the unsigned member. To get the true size of a variable of type PERSON, you would need to obtain the array size separately.
The size of the structure is added to the size of the array to get the total size to be allocated. After allocation, the array is copied to the array member of the structure, as shown below:
The compiler needs to be able to decide on the offset of every member within the struct. That's why you're not allowed to place any further members after an unsized array. It follows from this that you can't have two unsized arrays in a struct.
It is an extension from Microsoft, and sizeof(structure) == sizeof(structure_without_variable_size_array).
I guess they use the initializer to find the size of the array. If you have two variable size arrays, you can't find it (equivalent to find one unique solution of a 2-unknown system with only 1 equation...)
Arrays without a dimension are not allowed in a struct,
period, at least in C++. In C, the last member (and only the
last) may be declared without a dimension, and some compilers
allow this in C++, as an extension, but you shouldn't count on
it (and in strict mode, they should at least complain about it).
Other compilers have implemented the same semantics if the last
element had a dimension of 0 (also an extension, requiring
a diagnostic in strict mode).
The reason for limiting incomplete array types to the last
element is simple: what would be the offset of any following
elements? Even when it is the last element, there are
restrictions to the use of the resulting struct: it cannot be
a member of another struct or an array, for example, and
sizeof ignores this last element.