Does "Int Size = 10;" Yield a Constant Expression

Does int size = 10; yield a constant expression?

This is variable length arrays or VLA which is a C99 feature but gcc and clang support it as an extension in C++ while Visual Studio does not. So Visual Studio is adhering to the standard in this case and is technically correct. Not to say that extensions are bad, the Linux kernel depends on many gcc extensions, so they can be useful in certain contexts.

If you add the -pedantic flag both gcc and clang will warn you about this, for example gcc says (see it live):

warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[size];
^

Using the -pedantic-errors flag will make this an error. You can read more about extensions in these documents Language Standards Supported by GCC and clangs Language Compatibility section.

Update

The draft C++ standard covers what is a integral constant expression in section 5.19 Constant expressions paragraph 3 and says:

An integral constant expression is an expression of integral or unscoped enumeration type, implicitly converted to a prvalue, where the converted expression is a core constant expression. [...]

It is not intuitively obvious from reading this what all the possibilities are but Boost's Coding Guidelines for Integral Constant Expressions does a great job of that .

In this case since you are initializing size with a literal using const would suffice to make it an integral constant expression (see [expr.const]p2.9.1) and also bring the code back to being standard C++:

const int size = 10;

using constexpr would work too:

constexpr int size = 10;

It would probably help to read Difference between constexpr and const.

For reference the equivalent section to 8.3.4 paragraph 1 in the C99 draft standard would be section 6.7.5.2 Array declarators paragraph 4 which says (emphasis mine):

If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope;124) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

Is variable defined by const int determined at compilation time?

The compiler must generate code "as if" the expression was evaluated at
compile time, but the const itself isn't sufficient for this. In
order to be used as the dimension of an array, for example, expression
N must be a "constant integral expression". A const int is
a constant integral expresion only if it is initialized with a constant
integral expression, and the initialization is visible to the compiler.
(Something like extern int const N;, for example, can't be used in
a constant integral expression.)

To be a constant integral expression, however, the variable must be
const; in your second example, the behavior of the compiler and the
resulting program must be "as if" the expression were only evaluated at
runtime (which means that it cannot be used as the dimension of an
array). In practice, at least with optimization, the compiler likely
would evaluate N at compile time, but it still has to pretend it
can't, and refuse to compile the code.

Array size allocation at compile time, expecting constant value

C++ doesn't support arrays with size determined at run-time. You could switch to using the Vector class instead.

std::vector<Data_point > graph;

To follow the logic you're using: In PlotThis you could use std::vector::resize to resize the container to contain n elements.

void PlotThis(unsigned int n){
graph.resize(n); // Resize Vector container
...

Also with std::vector:

"compared to arrays, vectors consume more memory in exchange for 
the ability to manage storage and grow dynamically in an efficient way."

This means you have the option to not worry about specifying the size of the vector and just adding elements as you need to. So you could have a loop determine how many elements are added (n) in your method - possible to use std::vector::push_back. If you do this then just make sure to clear the vector at some point so you don't re-use old data - possible to use std::vector::clear.

C++: int calculations during compile time (not during running time)

Is this calculation done during compile time?

Yes, compilers did a lot optimizations and calculations for you, the initialization in your code is ok even without any optimization, and it's the result of pre-calculation of compiler.

Generally, calculation here includes the constexpr, const type declaration and so on, which are already in the definition of language itself(see constant expression).

compile-time const and example

just see the output of the example.

compile-time constexpr and example

The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time.


This is how array can be initialized, an array declaration is as below:

noptr-declarator [ expr(optional) ] attr(optional)

here, expr is:

an integral constant expression (until C++14) a converted constant expression of type std::size_t (since C++14), which evaluates to a value greater than zero

which are all constant expression, which says:

an expression that can be evaluated at compile time.

So, using the so-called pre-calculation to initialize an array is ok.

Here's also a follow-up: there're also a lot of ways to save more calculations and time by let them done during compile time, and they are shown in the link above.


Just to mention something different: As for optimizations, you can see the difference between the assembly codes of version -O0 and -O3 when calculating the sum from 1 to 100, it's a jaw-breaker -- you'll see the result 5050 is in the assembly code in the -O3 version, it's also a kind of compile-time calculation, but not enabled for all kinds of situation.

Why doesn't this code generate an error on using a variable array size?

C99 accepts variable length arrays, and gcc accepts them as an extension in C90 and C++.

Using -pedantic or -Wvla turns this into a warning in C++ code, and -Werror=vla turns it into an error.

Defining arrays with(out) constant expressions

Variable-length arrays (that is, arrays whose size is determined by a non-constant expression) are allowed in C, and some C++ compilers allow them as an extension to the language. GCC is one such compiler.

You'll get a warning if you compile with -pedantic or -Wvla, or an error with -pedantic-errors. Use those flags if you want to avoid non-standard compiler extensions.



Related Topics



Leave a reply



Submit