C++ Variable expressions for defining array size? - c++

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);

Related

C++ array size declaration and const

I'm just jumping into C++, coming from C
In C (89/90), a const is not actually a constant (as opposed to a #define'd, enum, or literal), but rather read-only once set. I.e, I can:
const int x = rand();
and that's fine - the point being x isn't known until runtime. Hence, I can't
int arr[x]; // error - x is not a compile-time constant
Then, one of the C standards (99?) went ahead and allowed for variable-length arrays. Although I normally code against the ANSI standard in C, this has actually had an impact now that I am trying to pickup C++11.
As far as I know, C++ does not allow for variable-length arrays. However, many compilers allow it as an extension (GCC ?). The problem is, now that I am trying to learn C++11, I can't tell if what I'm coding is valid C++, or C++ extended with C99-compatibility. Ex:
std::default_random_engine e{};
std::uniform_int_distribution<int> d{};
const int x{d(e)};
int arr[x]; // compiles
I can't tell if this is valid C++ or not. Clearly, the value of x is not known until runtime. I think I may not understand the difference between C and C++ const?
You are correct VLAs are a C99 feature(optional in C11) and the C++ standard does not include this feature although both gcc and clang allow them in C++ as an extension. We can see they are not allowed by going to the draft C++11 standard section 8.3.4 Arrays which says:
D1 [ constant-expressionopt] attribute-specifier-seqopt
^^^^^^^^^^^^^^^^^^^^^^
For both gcc and clang using the -pedantic flag will warn when you are using an extension. If you are targeting C++11 then you should also specify that using -std=c++11. You can use -pedantic-errors to turn the warning into errors. If you compile your code using -pedantic you should see the the following warning:
warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[x]; // compiles
^
gcc documents their support for various standards, defaults and flags to enforce standard on their Language Standards Supported by GCC page and it says:
to obtain all the diagnostics required by the standard, you should
also specify -pedantic (or -pedantic-errors if you want them to be
errors rather than warnings).
In general clang supports what gcc does but you can find more details on their Language Compatibility page.
Note as mentioned by GingerPlusPlus std:vector is considered the alternative for VLA in C++.

Defining the size of array using variable

Is this valid in C language?
#include <stdio.h>
int main()
{
int i = 5;
int a[i]; // Compiler doesn't give error here. Why?
printf("%d",sizeof(a)); //prints 5 * 4 =20. 4 is the size of integer datatype.
return 0;
}
Compiler doesn't give error at the statement int a[i];. i isn't a constant then how can it compile successfully? Is it because I am using gcc compiler? Is it allowed in C++?
Yes, this is valid as of C99, and is called a variable-length array (VLA). In other words, it has been in an official language standard for around 14 years.
No, it's not valid in C++, see this question for details.
Also note that sizeof is not a function, so that can be written as printf("%zu\n", sizeof a); which also uses the proper format specifier for a size_t value.
This is valid C99 it is called Variable Length Array(VLA) gcc supports VLA as an extension outside of C99 mode with respect to C++ both gcc and clang support variable length arrays as an extension even though this is really a C99 feature.
You can build using the -pedantic argument in gcc and clang both will give a warning similar to the following:
warning: variable length arrays are a C99 feature [-Wvla-extension]
sizeof is expected to work correctly with VLA although it will be evaluated instead of an integer constant. Although you do have undefined behavior in your code since you specified the wrong format specifier for size_t which is zu and not d. The C99 draft standard in section 7.19.6.1 The fprintf function which printf's section refers back to for the format string paragraph 9 says:
If a conversion specification is invalid, the behavior is undefined.[...]
I'd just add to unwind's answer that in C++14, there will be runtime-sized arrays, which work pretty much the same as VLA.
See chapter 8.3.4 in N3690 (array of runtime bound of T)
They seem to be supported in clang-3.3 (in C++1y mode), but NOT in GCC 4.8 (the support should come in GCC 4.9).
When you write the code in pre-C++14 mode (c++03, c++11), your code will probably compile, but it should issue a warning about using a C99 feature not supported in C++.
And you always should compile with most pedantic warnings enabled :)
Sizeof operator is compiler independent.
You could read more about this in the following links ::
VLA-as-function-argument

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.

can we give size of static array a variable

hello every one i want to ask that i have read that we can declare dynamic array only by using pointer and using malloc or newlike
int * array = new int[strlen(argv[2])];
but i have wrote
int array[strlen(argv[2])];
it gave me no error
i have read that static array can only be declared by giving constant array size but here i have given a variable size to static array
why is it so thanks
is it safe to use or is there chance that at any latter stages it will make problem i am using gcc linux
What you have is called a variable-length array (VLA), and it is not part of C++, although it is part of C99. Many compilers offer this feature as an extension.
Even the very new C++11 doesn't include VLAs, as the entire concept doesn't fit well into the advanced type system of C++11 (e.g. what is decltype(array)?), and C++ offers out-of-the box library solutions for runtime-sized arrays that are much more powerful (like std::vector).
In GCC, compiling with -std=c++98/c++03/c++0x and -pedantic will give you a warning.
C99 support variable length array, it defines at c99, section 6.7.5.2.
What you have written works in C99. It is a new addition named "variable length arrays". The use of these arrays is often discouraged because there is no interface through which the allocation can fail (malloc can return NULL, but if a VLA cannot be allocated, the program will segfault or worse, behave erratically).
int array[strlen(argv[2])];
It is certainly not valid C++ Standard code, as it is defining a variable length array (VLA) which is not allowed in any version of C++ ISO Standard. It is valid only in C99. And in a non-standard versions of C or C++ implementation. GCC provides VLA as an extension, in C++ as well.
So you're left with first option. But don't worry, you don't even need that, as you have even better option. Use std::vector<int>:
std::vector<int> array(strlen(argv[2]));
Use it.
Some compilers aren't fully C++ standard compliant. What you pointed out is possible in MinGW (iirc), but it's not possible in most other compilers (like Visual C++).
What actually happens behind the scenes is, the compiler changes your code to use dynamically allocated arrays.
I would advice against using this kind of non-standard conveniences.
It is not safe. The stack is limited in size, and allocating from it based on user-input like this has the potential to overflow the stack.
For C++, use std::vector<>.
Others have answered why it "works".

statically define an array based on a variable value C/C++

I want to define a 2D array statically. The size of the array is determined by a variable.
How do I do this? I do not want to dynamically define the array. I heard that there is a way to do this.
Answer is No You Cannot in C++.
Dimensions of the array must be known at compile time.
int my_array[6][7]; // okay
int my_array[H][7]; // ISO C++ forbids variable length array
int my_array[6][W]; // ISO C++ forbids variable length array
int my_array[H][W]; // ISO C++ forbids variable length array
Some compilers do support Variable Length Arrays(VLA) through their own extension but VLA are not defined in the C++ standard, hence using VLA will be non conforming to C++ standard.
VLA's were introduced in C99 C standard. C++ was branched out from C standard of C98. By the time C introduced VLA, C++ already had Vectors and had no need to support or encourage VLA. Hence, VLA was never formally accepted in the C++ Standard, some C++ compiler still support VLA through compiler extensions.
Since, you tagged your Q C as well as C++, to summarize the answer:
In C99 & versions after that : You Can
Versions before C99: You Can't
In C++(Any version): You can(through compiler extensions) but You should'nt
Here is the legendary C++ FAQ which explains everything about arrays.
I learned a lot from it. :)
If one of the dimensions of the array is variable, then the size must be variable, then it must be dynamically sized - or sized in such a way that the the array is statically sized larger than the largest value that the variable could be.
I dont think so you can statically define it! However you can use vector but underneath it too does dynamic allocation for you
By "variable", I assume you're talking about a non-constant value.
In C99, yes:
int size = ...;
int array[size][size];
In C++, you can't. The alternative is to use pointers and dynamic allocation (or better yet, vectors).
In C versions prior to C99, it's also impossible. Use malloc().
This depends where and when the variable is initialized. If its something done at compile time you can use templates to get it done: template </* args */> struct ConstExpr{enum{value = /* math goes here */};};, else its impossible without selfmodifying code(and I'm pretty sure this is gonna very dangerous, because you'll need to alter the PE so you can somehow get your allocated space change before its virtualized).