Is creating arrays with runtime bounds allowed in c++? - c++

According to
C++ : Creating an array with a size entered by the user
creating arrays with runtime bounds is not allowed in c++.
But I get below code compiled without errors.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
cin>>n;
int a[n][n];
a[n-1][n-1]=9;
cout<<a[n-1][n-1]<<endl;
return 0;
}
and it works fine too. check it here ->
http://cpp.sh/6bies
Can someone help to solve this confusion?.

Is creating arrays with runtime bounds allowed in c++?
Such arrays are ill-formed.
But I get below code compiled without errors. ... and it works fine too.
The C++ standard does not disallow compilers from successfully compiling ill-formed programs. It is sufficient to show a diagnostic message. This allows compilers to extend the language.
If you take a look at the compiler output of your example, you'll find that the compiler did tell you about it, as is required by the C++ standard:
15:15: warning: array of array of runtime bound [-Wvla]
So, it appears that your compiler supports arrays of runtime bound - and even arrays of arrays of runtime bound - as a language extension.
Most compilers can be asked to refuse programs that are ill-formed according to C++ standard, if you so prefer.
It is standard compliant to create arrays of runtime bound in dynamic storage. The simplest way is to use std::vector.

If you are using gcc, it has some extensions, one of them being support for variable length arrays (VLA) that is available in C99.

Related

C++ Variable expressions for defining array size?

I'm a newb at C++ and I practice coding on my school computer, so I have to use an online compiler (www.CompileOnline.com). I have a variable that is defined by a function and is then used to initialize an array like so:
int var = function(a);
int num[var];
This code works just fine on the website, but on Visual Studio Express 2012 it gives me an error:
C2057: expected constant expression
Is this a problem with Visual Studio? I've read that it's a C++ rule, but then why does it work on the website? Any help is appreciated, thanks.
The feature that the code snippet requires is called variable length arrays (VLAs). Support for this feature in the C or C++ language depends on the compiler and the version of the standard.
C99 supports VLAs as standard.
Versions earlier than C99 (includes C90) do not support VLAs as standard, but some compilers may implement it as a language extension.
C11 makes VLAs an optional feature.
C++14 supports a restricted variant of VLAs called dynamic arrays.
Versions earlier than C++14 (includes C++11, C++03, and C++98) do not support VLAs as standard, but some compilers may implement it as an extension.
In particular, GCC implements VLAs as a language extension for C90 and C++, and apparently www.compileonline.com uses GCC as the compiler (version 4.7.2 as of this writing). No version of the Visual C++ compiler implement VLAs.
Herb Sutter talks about C++14's dynamic array feature:
In the language, draft C++14 now allows stack-based arrays to have a size determined at run time:
void f(std::size_t n)
{
int a[n];
...
}
Note that this is not the same as C99 variable length arrays (VLAs),
and that the C11 standard has made VLAs conditionally-supported so
that they are no longer part of portable C required in a conforming C
compiler. In particular, C++ explicitly not does support the following
features from C99 VLAs which C++ feels are not desirable:
multidimensional arrays, where other than the top level has a runtime
bound (in analogy, the array form of new expressions doesn’t support
that either)
modifications to the function declarator syntax
sizeof(a) being a runtime-evaluated expression returning the size of a
typedef int a[n]; evaluating n and passing that through the typedef
If you want C++ code that works in pretty much any version of C++, consider using std::vector instead:
#include <vector>
int main()
{
int var = function(a); // Assume function() has been defined.
std::vector<int> num(var); // Creates a vector with var number of elements.
// ...
int num1 = num[1]; // You can access elements in vectors just like arrays.
num[1] += 10;
// ...
}
Variable length arrays are not allowed in C++. The size of the array must be determinable at compile time.
CompileOnline.com says it uses GNU GCC version 4.7.2. GCC has an extension that supports variable length arrays in C++:
Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++.
It seems the online compiler is gcc which implement variable length arrays as an extension in C++. The "problem" in this case is actually gcc, not VC++: gcc implement an extension which enables by default, tricking users into creating non-portable code.
If you need a variable sized array in C++, you'd include <vector> and use the class template declared in this header, e.g.:
int var = function(a);
std::vector<int> num(var);

Declaring an array using const integer

I was trying to declare an int array in C++ and found this problem. The following code runs fine on g++ compiler but the compilation fails on Visual Studio. I was following Bruce Eckel and found this code.
#include<iostream>
int main()
{
const int j = std::cin.get();
char buf[j];
}
Keeping j just an int would be a problem, that I understand. Since the value of j would be const during the run-time, the program should get compiled. Please correct me if I am wrong anywhere.
Since the value of j would be const during the run-time, the program should get compiled.
No, the const-ness of j is irrelevant here. C++ currently only supports statically-sized C-arrays. Its size must be a compile-time constant.
If you want an array of dynamic size, use std::vector.
The fact that g++ by default compiles this is a bit unfortunate (for compatibility). You should use the -pedantic flag when using g++ to ensure that such compiler extensions aren’t enabled (using compiler extensions of course isn’t bad in itself, but in this case there’s not really any advantage).
You are trying to define buf as a variable-length array. This is a feature of C (not C++) that is supported by g++ as a non-standard extension. Evidently your other compiler does not support it.
I would suggest turning buf into std::vector<char> (or indeed std::string?)
Variable length arrays are C99 feature both gcc and clang supports them as an extension in C++ but Visual Studio never did and even though they recently added support for C99 is it not supported in C++
Since you are developing in C++ unless you have a good reason to not use it then std::vector or std::string should be sufficient.
I had the same problem. It seems very difficult to create an array of which its length is stored as a variable. What I did is create an additional function:
void Class:: initMyArray(const int size) {
myArray = new int[size]
}
Now, you just have to call that function and give it your variable. I'm not sure whether this is a proper solution though (I'm not a C++ expert).

define the length of an array with a variable in c++/c

I am reading a book saying that in C++ you can't do this:
int array_size = 3;
int array[array_size];
Then I tried it with gcc,but it didn't complain at all(exception warned about unused array).
Also I read about this question.The 4th answer says that you can use something like this:char someCondition[ condition ];To me the condition would only be known until runtime,so the whole thing seems really confounding to me.Can anyone help explain this?
Thanks,G
If You are using a C++ compiler it works because most of the C++ compilers provide a compiler extension that supports Variable Length arguments(VLA).
If You are using a C compiler it works because the standard allows it.
In C++, VLA are not allowed by the C++ Standard, so any usage of it through compiler extensions will make your code non portable.
C++ provides std::vector or std::array(C++11) which satisfy all the requirements using variable length array or c-style arrays resp and you should use them.
Note that,since C99 standard, VLA's are allowed in C.

const problem in VS2010

I have the shortest question possible:
Why does this not work in VS2010?
string keyword("lookuptable");
const int kwSize = keyword.size();
char oldBuffer[kwSize+1];
It works perfectly in GCC. VS2010 tells me that
"expression must have constant value"
I am using Win32 console application / empty project.
I am using absolutely nothing special, just
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
using namespace std
and its a single main function in a cpp file.
The size of an array must be an integral constant expression, or ICE (which means that it must be known at compile-time). You can use a const int in an ICE, but only if its initializer is itself an ICE.
A function call, like keyword.size() is not usable in an ICE, so kwSize is not usable in an ICE.
If it "works perfectly" in gcc it is either due to a bug or a language extension of some sort.
In C++0x, some function calls can be used in integral constant expressions, but they must be constexpr functions and there are restrictions on their use. To the best of my knowledge, no compiler fully supports constexpr yet. In any case, std::string::size is not constexpr.
GCC has a language extension allowing variable-length arrays. Visual C++ does not. You must initialize stack-based arrays with a fixed, compile-time constant.
As others have mentioned, non-constant array bounds are a GCC extension (likely a side benefit of its C99 support - C99 does allow non-constant array bounds). If you want this in C++, you should use a vector:
std::vector oldBuffer(kwSize + 1);
To turn this into a char *, do:
&oldBuffer[0]
This, while not strictly speaking valid C++ prior to C++0x, works properly in every compiler I've come across so far. C++0x retroactively blesses this usage, and also provides a oldBuffer.data() equivalent.
the answer is there "expression must have constant value". The const has to be something resolved at the compile time.
keyword.size() is evaluated at runtime therefore it is not a compile time constant. Depending on the compiler it may not be allowed to use an array size that is depending on some runtime value.
Some further info about variable array length in gcc

Non-const declaration of array

I have been teaching myself programming for couple of years, and I was sure that if you need array declaration of a variable number you need to use malloc or new.
Today I found that this compiles under g++ version 4.4.4, without warnings or errors:
#include <iostream>
using namespace std;
int main()
{
int size_array;
cin >> size_array;
int iTable[size_array];
for(int i=0;i < size_array;i++)
iTable[i]=i*i;
for(int i=0;i < size_array;i++)
cout << iTable[i] << endl;
return 0;
}
Also it compiles completely fine if you are using gcc (after changing cout and cin with printf and scanf)
Under Visual Studio this code fails to compile since size_array is not constant.
When this was changed? This is a safe method?
This is a C99 feature - VLA - which is not a part of standard c++. You can use it if your compiler supports it and you don't require portability. If the compiler supports it, it's perfectly safe to use - but it's a bad habit using non-standard features.
This is a compiler extension of gcc, not standard.
No thats not safe at all. It could corrupt your stack.
See http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.20.
Simply put, in C99, this is called VLA and is part of the standard (correct me if I'm wrong) but in C++ this is not part of the standard. If you need this functionality use std:vector instead.
This depends if you are writing C or C++. I'll assume C as for c++ you would be better off using std::vector rather than an array.
In C it depends which versiuon you are using. If and only if you are using a C99 standard compiler then the array can take its size from a variable at run time as you do here otherwise the size must be defined at compile time. Visual Studio does not support the dynamic array - see MSDN
C++ uses the C89 standard so requires the size to be set at compile time.
So in your case you need to see what flags you passed to the compiler.
As noted by #Eric the code is C++ so the working compiler is using a non standard extention so for gnu I would add flags to enforce a standard e.g. -ansi or -std=c++98 and -pedantic
There is an extension of GCC mimicking C99 Variable Length Arrays. It's not standard C++.
However, even if you have this turned off, the posted code can compile. The standard does not require a diagnostic for this case: it's Undefined Behaviour, not an error.
In really obvious cases a compiler may choose to prevent you from writing this, but otherwise it is free to let you fail in peace.
Conclusion: don't be fooled by the compilation. It's still bad and wrong.
You can get this functionality in C or C++ with alloca (_alloca on Windows). std::vector is NOT a substitute: it is allocated on the heap, with new, which calls malloc, which is potentially expensive.
There is a good reason why you might want to have an array whose length is determined at runtime allocated on the stack: it's really fast. Suppose you have loop that executes frequently but has an array that depends on something at runtime (say, the size of your canvas widget). You can't just hard-code a number: your program will crash when we all get 36" 300 dpi Retina-display monitors and pixels[2400] is no longer safe. But you don't want new, or your loop hits a malloc and gets slow.
Although, for large arrays, it might be better to have a std::vector that is static to the function an only gets resized (larger) when necessary since your stack has limited size.
(See http://msdn.microsoft.com/en-us/library/wb1s57t5(VS.71).aspx)
It's okay to use the feature if you are using c99.
You have to be very careful about the value of size. a large value will overflow your stack, and your process may go insane.