I am trying to use an array that can change in length by the number in the command line. Arrays must be constant at the time of declaration. Can anyone help?

using namespace std;

int main (int argc, char *argv[])
{
int nulls=atoi(argv[2]);
int arry[nulls];

}

Dani AI

Generated

As discovered, the compiler errors (C2057 / C2466 / C2133) mean the array bound must be a compile-time constant. As explained, const int nulls = atoi(argv[2]); is not a compile-time constant because atoi runs at runtime. ’s “it works for me” and ’s g++ result are explained by a compiler extension (some versions of GCC accept variable-length arrays in C++ as a nonstandard extension) — not portable and not guaranteed.

A portable, safe pattern is to parse and validate the command-line value, then use a runtime container that manages storage (RAII). Example using strtol + std::vector:

#include <cstdlib>
#include <cerrno>
#include <climits>
#include <vector>
#include <iostream>

int main(int argc, char* argv[]) {
    if (argc < 3) return EXIT_FAILURE;
    char* end = nullptr;
    errno = 0;
    long v = std::strtol(argv[2], &end, 10);
    if (end == argv[2] || *end != '\0' || errno == ERANGE || v <= 0) {
        std::cerr << "invalid or out-of-range count\n";
        return EXIT_FAILURE;
    }
    std::size_t n = static_cast<std::size_t>(v);
    std::vector<int> data(n); // runtime-sized, exception-safe
}

If raw arrays are required for interop, use RAII smart pointers instead of manual new[]/delete[]:

#include <memory>
// after validating n
auto arr = std::make_unique<int[]>(n); // C++14+, automatically freed

Troubleshooting notes: MSVC enforces the standard rule (array size must be an integral constant expression). constexpr can create compile-time constants only when the initializer itself is constant. Avoid relying on compiler extensions (GCC VLAs) for portability. Validate argc, check for negative/huge values, and prefer std::vector or smart pointers for safety and maintainability.

Recommended Answers

All 6 Replies

AFAIK this should work:

const int nulls=atoi(argv[2]);
int arry[nulls];

AFAIK this should work:

const int nulls=atoi(argv[2]);
int arry[nulls];

it still wont accept the code even with the const.

It works for me. What error message do you get?

It works for me. What error message do you get?

error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0 error C2133: 'arry' : unknown size

Worked for me even without the const on g++ 3.4.2. Was it crashing on you when you tried to run it at that point?

>int nulls=atoi(argv[2]);
>int arry[nulls];

Nope, sorry. C++ doesn't allow an array size that isn't a compile-time constant.

>const int nulls=atoi(argv[2]);
>int arry[nulls];

Bzzt! Wrong! nulls is still not a compile-time constant despite being qualified as const. This is because to be truly compile-time, the variable needs to be qualified as const (oxymoron?), and the value being assigned must be a compile-time constant as well. atoi is a function that produces a result at runtime, so the value being assigned to nulls is not a compile-time constant, and nulls is also not a compile-time constant because it's incomplete until the initialization value is generated. Therefore, nulls cannot be used to declare an array size.

>It works for me.
This is the mating call of mediocre programmers. Just because it works for you doesn't mean it works for everyone. You're relying on the extended behavior of your compiler, which means that your code only works on your compiler (and possibly even that specific version of your compiler). Moving to a different compiler and/or version means your code could likely stop working for you.

Now for the correct answer. Option 1 is to use a vector:

#include <cstdio>
#include <cstdlib>
#include <vector>

int main ( int argc, char *argv[] )
{
  if ( argc < 3 )
    return EXIT_FAILURE;

  std::vector<int> a ( atoi ( argv[2] ) );

  //...
}

This is the recommended solution. Vectors are safer and easier to use than the next solution, which is simulating an array using a pointer and dynamic allocation:

#include <cstdio>
#include <cstdlib>

int main ( int argc, char *argv[] )
{
  if ( argc < 3 )
    return EXIT_FAILURE;

  int *a = new int[atoi ( argv[2] )];

  //...

  delete [] a;
}

Both of these solutions support array-like behavior. However, the vector also has the benefit of extended information (like the size) through member functions, and a wide range of supporting utility functions for working with the data. With the simulated array, it's far less convenient.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.