1

Possible Duplicate:
C/C++: Array size at run time w/o dynamic allocation is allowed?

In the following listing, clearly size of buf is determined by run-time constant j. How does compiler generate code to allocate storage on stack(not knowing value of j at compile time)?

#include<iostream>
#include<cstdlib>

using namespace std;

int main(){
  srandom(time(NULL));    
  int i = random();
  cout<< "random number: "<<i<<endl;
  if(i%2==0)
    i=2;
  else
    i=1;
  const int j=i;
  char buf[j];
  std::cout<<"size of buf array: "<<sizeof(buf)<<endl;
  return 0;   
}
Community
  • 1
  • 1
amirmonshi
  • 649
  • 5
  • 19
  • 5
    Let me guess ... you're compiling this using g++? That's a non-standard extension allowing C99's VLAs. C++ does not allow them. Compile with -pedantic and / or -Wall – Praetorian Mar 21 '12 at 20:59
  • 2
    `objdump -d -S my_file` if you want to see the code generated by the compiler for that line. Also, with `-pedantic` (assuming g++): `warning: ISO C++ forbids variable length array ‘buf’` – AusCBloke Mar 21 '12 at 21:03
  • Exactly! got the warning with `-pedantic` but not with `-Wall` though. – amirmonshi Mar 21 '12 at 21:08

3 Answers3

5

I'm assuming that you are using gcc, and hence the VLA extension. This is not standard C++ and it was dropped from C++0x (1x).

The reasoning is that it is not really all that useful and that a C++ implementation would be much more complex than one in C due to the stronger type system.

Really, if you are stack allocating arrays of unknown size, you are at the same time writing dangerous code that may very well blow the stack. If you know the size then it is a non-issue, otherwise just dynamically allocate it. There are of course perfectly valid use cases and it is a "nice to have" feature, but they ultimately decided against it.

Here is a good run down on the subject.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • To say that it was dropped from C++11 is very misleading. It has NEVER been part of Standard C++. It was proposed for inclusion during the C++11 draft process, but rejected. And that newsgroup thread misses out on the point entirely, IMO, since it totally ignores the differences in behavior between arrays of PODs (which C VLAs are) and arrays of non-trivial objects. – Ben Voigt Mar 22 '12 at 02:07
4

A conforming C++ compiler won't accept your code. Despite being a const, j isn't a constant expression.

gcc accepts this in C++ code as an extension (according to the language standards, it's only permitted in C99 code). Basically, it's allocating space on the stack for buf. It (typically) does that by subtracting some amount from the current stack pointer. From a viewpoint of the code that's generated, it's pretty trivial to deal with that being non-constant on a typical machine.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • @BenVoigt: You of course know this, but we are talking C++, and C99 certainly does not apply to it. – Ed S. Mar 21 '12 at 21:04
  • @EdS: Sure, but Jerry referred to "gcc", which is both. And the `gcc` command is the C compiler portion of gcc, which further confuses matters. – Ben Voigt Mar 21 '12 at 21:07
  • I compiled it with g++ command. I guess then the C portion of gcc shouldn't apply here? – amirmonshi Mar 21 '12 at 21:29
  • @amirmonshi: it's mostly the same compiler either way, though it runs in two different modes. In theory, in C++ mode (if it was following the standard exactly) it wouldn't accept this, but they apparently consider it useful enough to have enabled it in C++ mode as well as C mode. – Jerry Coffin Mar 21 '12 at 22:13
0

The compiler just has to increase the stack size and point the buf variable at the newly created space on the stack. There is no reason this can't be done dynamically given a size at runtime. (Although it may not be wise to do from a programming perspective.)

Nathan S.
  • 5,244
  • 3
  • 45
  • 55
  • No reason, except for the fact that C++ requires every variable to have a constant size (formally a *constant integral expression*) known at compile time. – Ben Voigt Mar 22 '12 at 02:08
  • @BenVoigt Yes, but the question was "How can the compiler do this?" The answer to that is simple. All the other discussion is important information but doesn't necessarily answer the question of how the compiler does it. – Nathan S. Mar 22 '12 at 03:58