int x[a][b] leads to compilation errors

D

Disc Magnet

I wrote this program.

#include <iostream>

using namespace std;

int f(int a, int b)
{
int x[a];
cout << sizeof(x) << endl;
}

int test_array_size() {
f(5, 6);
}
int main()
{
test_array_size();
}

If I compile this with g++ on Linux and run it, it compiles and runs
fine. The output is: 120.

However, if I try to compile this with Visual Studio 2005, I get these
errors:

1>helloworld.cpp
1>./src/helloworld.cpp(7) : error C2057: expected constant expression
1>./src/helloworld.cpp(7) : error C2466: cannot allocate an array of
constant size 0
1>./src/helloworld.cpp(7) : error C2057: expected constant expression
1>./src/helloworld.cpp(7) : error C2466: cannot allocate an array of
constant size 0
1>./src/helloworld.cpp(7) : error C2087: 'x' : missing subscript
1>./src/helloworld.cpp(7) : error C2133: 'x' : unknown size
1>./src/helloworld.cpp(8) : error C2070: 'int [][1]': illegal sizeof
operand
1>Exception: error status 2 from C:\Program Files\Microsoft Visual
Studio 8\VC\bin\cl.exe

Could you please explain, why this difference in behavior?
 
I

Ian Collins

Disc said:
I wrote this program.

#include <iostream>

using namespace std;

int f(int a, int b)
{
int x[a];


This is a gcc extension, not part of standard C++.
If I compile this with g++ on Linux and run it, it compiles and runs
fine. The output is: 120.

However, if I try to compile this with Visual Studio 2005, I get these
errors:

As expected, VS doesn't support that extension.
 
R

Robert Fendt

I wrote this program.
[...]
If I compile this with g++ on Linux and run it, it compiles and runs
fine. The output is: 120.

If I compile it using GCC 4.4 in Standard C++ mode, I get the
following errors.

t.cpp: In function ‘int f(int, int)’:
t.cpp:7: error: ISO C++ forbids variable length array ‘x’
t.cpp:7: error: ISO C++ forbids variable length array ‘x’
t.cpp:9: error: no return statement in function returning non-void
t.cpp: In function ‘int test_array_size()’:
t.cpp:13: error: no return statement in function returning
non-void

The difference being of course, that my default switches are
"-ansi -pedantic -Wall -Werror". The ISO C90 and C++98 standards
explicitely state that the size specifiers of an array must be
constant expressions, i.e., the compiler must be able to deduce
the storage size of the array at compile time.

If the size of an array is not known at compile time, in C90
you can only use malloc. In C++98, you can use array-new, but
that still needs to now all dimensions safe one. I.e. This
actually works, but is probablx not what you want:

int(*x)[5] = new int[a][5];

Or you allocate with new int[a * b], and then access elements
using a small bit of math. Variable-length arrays are supported
by ISO C99, and by GCC in C90 and C++ mode as an extension:
http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

C++ does not really need them, since it has array-new and
std::vector (or even boost::array). C++ 0x will adopt them from
C99, AFAIK, but C++ 0x is not yet done, and there are no even
mostly complete implementations available yet.

Regards,
Robert
 
A

Anthony Delroy

If the size of an array is not known at compile time, in C90
you can only use malloc. In C++98, you can use array-new, but
that still needs to now all dimensions safe one. I.e. This
actually works, but is probablx not what you want:

int(*x)[5] = new int[a][5];

Or you allocate with new int[a * b], and then access elements
using a small bit of math. Variable-length arrays are supported
by ISO C99, and by GCC in C90 and C++ mode as an extension:http://gcc.gnu..org/onlinedocs/gcc/Variable-Length.html

C++ does not really need them, since it has array-new and
std::vector (or even boost::array). C++ 0x will adopt them from
C99, AFAIK, but C++ 0x is not yet done, and there are no even
mostly complete implementations available yet.

Many systems also have alloca(), which is closer to gcc's extension in
that the space comes from the stack (i.e. automatic), though
destructors - if any - aren't called.

Cheers,
Tony
 
S

SG

[...] C++ 0x will adopt them from C99, AFAIK,
but C++ 0x is not yet done, and there are no even
mostly complete implementations available yet.

I havn't checked lately but if I recall correctly C++ will not adopt
this.

Cheers,
SG
 
J

James Kanze

Disc said:
I wrote this program.
#include <iostream>
using namespace std;
int f(int a, int b)
{
int x[a];

This is a gcc extension, not part of standard C++.

It's also not present if you invoke g++ as a C++ compiler. Say
with something like "g++ -std=c++98 ...".
As expected, VS doesn't support that extension.

But it has a few others:). Regretfully, I don't know of any
compiler which will give you "just C++" when invoked with no
special options.
 
I

Ian Collins

SG said:
[...] C++ 0x will adopt them from C99, AFAIK,
but C++ 0x is not yet done, and there are no even
mostly complete implementations available yet.

I havn't checked lately but if I recall correctly C++ will not adopt
this.

That's my understanding as well. VLAs would introduce at least one
interesting ambiguity in C++:

const size_t size = 42;

int array[size]; // VLA, or array?
 
D

Disc Magnet

That's my understanding as well.  VLAs would introduce at least one
interesting ambiguity in C++:

const size_t size = 42;

int array[size];   // VLA, or array?

I tried a similar code with gcc as well as g++.

$ cat const_as_size.c
#include <stdio.h>

int main()
{
const int size = 10;
int a[size];

printf("sizeof a: %d\n", sizeof a);
return 0;
}

$ gcc -pedantic -ansi const_as_size.c && ./a.out
const_as_size.c: In function 'main':
const_as_size.c:6: warning: ISO C90 forbids variable length array 'a'
sizeof a: 40

However, with g++ it doesn't give any warnings.

$ cat const_as_size.cc
#include <iostream>

using namespace std;

int main()
{
const int size = 10;
int a[size];

cout << "sizeof a: " << sizeof a << endl;
return 0;
}
$ g++ -pedantic -ansi const_as_size.cc && ./a.out
sizeof a: 40

Are the language rules different when a const variable is used as the
length of an array?
 
I

Ian Collins

Disc said:
That's my understanding as well. VLAs would introduce at least one
interesting ambiguity in C++:

const size_t size = 42;

int array[size]; // VLA, or array?
I tried a similar code with gcc as well as g++.

$ cat const_as_size.c
#include <stdio.h>

int main()
{
const int size = 10;
int a[size];

printf("sizeof a: %d\n", sizeof a);
return 0;
}
Are the language rules different when a const variable is used as the
length of an array?

Yes. In C, const is somewhat broken. In C++, 'size' is a compile time
constant, in C it isn't.
 
R

Robert Fendt

That's because a 'const' does not declare a compile-time constant in C
(for whatever reason) like it does in C++.

Hence the ubiquitous use of preprocessor #defines for that
purpose in C. However, IMHO using macros for that purpose is
ugly, since e.g. they do not honour namespaces (okay, C does not
have those anyway).

Regards,
Robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top