1

Error message in text:

I'm studying the book C++ Primer and encountering a problem listed below when coding an answer for one exercise:

#include<iostream>
#include<vector>

using namespace std;

int main() {
int i  = 3;
const int ci = 3;
size_t si = 3;
const size_t csi = 3;
int ia[i];
int cia[ci];
int sia[si];
int csia[csi];
int another_a[] = {1,2,3};

int *pi = begin(ia);       // error here
// no instance of overloaded function "begin" matches the argument list -- 
// argument types are: (int [i])
int *pci = begin(cia);
int *psi = begin(sia);     // error here
// no instance of overloaded function "begin" matches the argument list -- 
// argument types are: (int [si])
int *pcsi = begin(csia);
int *p_ano = begin(another_a);

vector<int> v = {1,3,4};
const int m = v.size();
const size_t n = v.size();
int ma[m];
int na[n];
int *pm = begin(ma);    // error here
// no instance of overloaded function "begin" matches the argument list -- 
// argument types are: (int [m])
int *pn = begin(na);    // error here
// no instance of overloaded function "begin" matches the argument list -- 
// argument types are: (int [n])

system("pause");
return 0;
}

I can understand that the first two errors are because that those two arrays are not defined using an constant variable. But why the last two, even if I have converted the size of the vector into a constant variable, the compiler still reports an error?

enter image description here

I'm quite confused about this, I would appreciate a lot for your kindly answer or discussion no matter it works or not.

Gavin Xu
  • 78
  • 6
  • Declaring arrays with non constant indexes isn't standard c++. If you need dynamically sized arrays use `std::vector` – Alan Birtles Mar 04 '19 at 08:04
  • You should post error messages or (better) proper build log including compiler version as text. – user7860670 Mar 04 '19 at 08:05
  • I know that I should use const var to declare array, but I think that in the step "const size_t n = v.size()", I have already computed the result and store it into a const var. – Gavin Xu Mar 04 '19 at 08:07
  • @GavinXu arrays requires a *compile time constant* (simply put, a value which can be worked out by the compiler). You have a constant variable which is a different thing. There's no way the compiler can work the size of an arbitrary vector until the program runs. – john Mar 04 '19 at 08:09
  • @john Although the code can run normally during running stage, but during compiling stage this declaration is not allowed. This is what you mean, right? I got it!!! Thanks a lot!!! – Gavin Xu Mar 04 '19 at 08:18
  • @VTT Already posted. I know the reason now. Thanks for your help! – Gavin Xu Mar 04 '19 at 08:23

2 Answers2

3

First and foremost, you are using a compiler extension, but more on that later.

The standard begin overload which works for you is a template that accepts a reference to an array with a size that is a constant expression. In a nutshell, constant expressions are those expressions that a compiler can evaluate and know the value of during compilation.

A constant integer initialized with a constant expression like const int ci = 3;, can be used wherever a constant expression is required. So ci is, for all intents an purposes, a constant expression itself (equal to 3).

Modern C++ has a way to make such varaibles stand out as intended constant expressions, it's the constexpr specifier. So you could define ci like this:

constexpr int ci = 3;

It's exactly like your original code. But the same will not work for const int m = v.size();. Because constexpr requires a true constant expression as an initializer, unlike const. For a const variable is not necessarily a constant expression. It can just be a run-time variable that you cannot modify. And this is the case with m.

Because m is not a constant expression, what you defined is a variable length array. A C feature that is sometimes introduced as an extension by C++ compilers. And it doesn't gel with the std::begin template, which expects the array extent to be a constant expression.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • So the dimension of an array must be a compiling-time constant expression but not a running-time constant, right? If so, I know the reason now. Thank you very much for your kindly and detailed explanation ! – Gavin Xu Mar 04 '19 at 08:20
  • @GavinXu - One other thing. I don't know what you use to compile your code, but most compilers have options to turn off extensions. You should look into how yours can be configured to avoid extensions. It's very helpful when learning to know what is standard and what is not, and a compiler can tell you if you ask. – StoryTeller - Unslander Monica Mar 04 '19 at 08:22
  • For instance, GCC will complain if you add `-std=c++14 -pedantic-errors` – StoryTeller - Unslander Monica Mar 04 '19 at 08:23
  • I simply used VS-code extensions C/C++ for learning and configured it according to some tutorials on the Internet. Thanks for your further information. And do you have some recommendations? Should I directly use Visual Studio? – Gavin Xu Mar 04 '19 at 08:27
  • @GavinXu - You don't have to use the full VS. I never used VS-code, but I hear it's not bad. Just do some research into how to configure it to avoid extensions. It will help you in your learning, and once you know a thing or two you can make a conscious decision to turn extensions on. – StoryTeller - Unslander Monica Mar 04 '19 at 08:29
  • And btw, about "tutorials online". I never met a truly good one. It's usually better to use a [good, vetted, book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – StoryTeller - Unslander Monica Mar 04 '19 at 08:30
  • OK. I will search for how to improve it. Thanks. – Gavin Xu Mar 04 '19 at 08:32
  • Haha, I know that. I just configured the software according to Internet tutorial, but I am studying the book C++ Primer. – Gavin Xu Mar 04 '19 at 08:34
  • @GavinXu - Ha, yes. I overlooked it in your question, apologies. Good on you! – StoryTeller - Unslander Monica Mar 04 '19 at 08:36
0

Declaring arrays with non constant indexes isn't standard c++.

If you need dynamically sized arrays use std::vector.

Declaring a variable as const doesn't make it a compile time constant (required to declare a fixed sized array) it just means you can't modify it after it is declared.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60