
Dear developers. I send this both to the boost and the gcc developers. I have found a strange limitation for the size of an array. The error is the same both for boost 1.36 and for the array in gcc 4.3.2 (and in the gcc 4.4 snapshot I use). I am almost sure that it is a bug of gcc and not of the array implementation. Here is the code. #include<array> using namespace std; int main () { array<unsigned int, (1<<22)> a; // Create a big array a[(1<<22)-13]=0; // This give a segmantation fault } In contrast a C-array works fine. int main () { unsigned int a[1<<22]; a[(1<<22)-13]=0; } Since the naturale implementation of the array class is just a wrapper around the C-style array this is very strange. I tryed to track down the bug. You use the following implementation: template<typename T, unsigned int n> class array { T C[n]; public: typedef unsigned int size_type; T& operator[](size_type p) { return C[p]; } }; If we change the C[n] to an explicite new it works fine. template<typename T, unsigned int n> class array { T* C; public: typedef unsigned int size_type; array() { C = new T[n]; } T& operator[](size_type p) { return C[p]; } }; It seams that this resolves the bug. But I can not explain why. I tested the code with the intel compiler and it works fine for both implementations. So it seams that it is a gcc bug, that the first solution do not work. What happens here? Kind regards Andreas Klein

Andreas Klein wrote:
I have found a strange limitation for the size of an array. The error is the same both for boost 1.36 and for the array in gcc 4.3.2 (and in the gcc 4.4 snapshot I use). I am almost sure that it is a bug of gcc and not of the array implementation.
Here is the code.
#include<array> using namespace std;
int main () { array<unsigned int, (1<<22)> a; // Create a big array
a[(1<<22)-13]=0; // This give a segmantation fault }
In contrast a C-array works fine.
int main () { unsigned int a[1<<22];
a[(1<<22)-13]=0; }
Since the naturale implementation of the array class is just a wrapper around the C-style array this is very strange.
I tryed to track down the bug. You use the following implementation:
template<typename T, unsigned int n> class array { T C[n];
public: typedef unsigned int size_type; T& operator[](size_type p) { return C[p]; } };
I have no clue. But what does GCC do when you try the following? struct big_array { unsigned int C[1<<22]; unsigned int& operator[](unsigned p) { return C[p]; } }; int main () { big_array a; a[(1<<22)-13]=0; // ??? } Kind regards, -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center

Hello
I have no clue. But what does GCC do when you try the following?
I tried gcc 4.2 and 4.3 on Linux on a Intel(R) Core(TM)2 CPU T5500 @ 1.66GHz the version of boost is 1.36.
struct big_array { unsigned int C[1<<22]; unsigned int& operator[](unsigned p) { return C[p]; } };
int main () { big_array a; a[(1<<22)-13]=0; // ??? }
It crashes. Prehaps its some gcc bug. I have no real idea what is the problem. As I said: I send the same report to the gcc team. But I think it is also interesting for the boost team. Best wishes Andreas Klein

On Mon, Nov 24, 2008 at 2:01 PM, Andreas Klein <klein@cage.ugent.be> wrote:
Dear developers.
I send this both to the boost and the gcc developers.
I have found a strange limitation for the size of an array. The error is the same both for boost 1.36 and for the array in gcc 4.3.2 (and in the gcc 4.4 snapshot I use). I am almost sure that it is a bug of gcc and not of the array implementation.
Here is the code.
#include<array> using namespace std;
int main () { array<unsigned int, (1<<22)> a; // Create a big array
a[(1<<22)-13]=0; // This give a segmantation fault }
There is no bug. boost::array does no dynamic memory allocation, so you are creating a circa 30 MB array on the stack. This is enough to blow the stack size limit on most OSs.
In contrast a C-array works fine.
int main () { unsigned int a[1<<22];
a[(1<<22)-13]=0; }
Since the naturale implementation of the array class is just a wrapper around the C-style array this is very strange.
Sheer luck probably. You have gone beyond an implementation defined limit and it is UB. In fact using a C -style array might (or not) have blown the stack in the same way.
I tryed to track down the bug. You use the following implementation:
[ Sniped: code using new instead of a member array ]
It seams that this resolves the bug.
But you lose some nice properties of boost::array: no dynamic allocation and aggregate initialization. At this point you might as well use std::vector.
But I can not explain why. I tested the code with the intel compiler and it works fine for both implementations. So it seams that it is a gcc bug, that the first solution do not work. What happens here?
It is not a bug of gcc (although a warning would have been appreciated), just a manifestation of UB. It might be that the intel compiler sets the stack size limit higher, it disables stack overflow checking or simply you are just being lucky (or unlucky, depends on how you see it) and UB is not showing up as an hard crash. Morale: do not stack allocate huge objects. -- gpd

Hello
There is no bug. boost::array does no dynamic memory allocation, so you are creating a circa 30 MB array on the stack. This is enough to blow the stack size limit on most OSs.
In contrast a C-array works fine.
Since the naturale implementation of the array class is just a wrapper around the C-style array this is very strange.
Sheer luck probably. You have gone beyond an implementation defined limit and it is UB. In fact using a C -style array might (or not) have blown the stack in the same way.
I guess not. I submitt a minimal example. I found the problem in a big complicated computaion. With the C array it works fine no crash and gives the expected result.
It is not a bug of gcc (although a warning would have been appreciated), just a manifestation of UB. It might be that the intel compiler sets the stack size limit higher, it disables stack overflow checking or simply you are just being lucky (or unlucky, depends on how you see it) and UB is not showing up as an hard crash.
Morale: do not stack allocate huge objects.
Do have a reference for me were to find the implementation limits? Would it a good idea to add a static assert to boost::array that ensures that the array size is small enough? I think a error message at compile time is more help full than Segmentation fault at run time. Best wishes Andreas Klein

Do have a reference for me were to find the implementation limits?
<snip/> ulimit on UNIX-like operating systems.
Would it a good idea to add a static assert to boost::array that ensures that the array size is small enough? I think a error message at compile time is more help full than Segmentation fault at run time. On UNIX-like operating systems, the available stack size is usually defined at run-time, and can often be tweaked per process. How much stack memory you can safely allocate and use depends on that, so it's hard to provide a compile time error.
Jens

Do have a reference for me were to find the implementation limits? ulimit on UNIX-like operating systems.
Would it a good idea to add a static assert to boost::array that ensures that the array size is small enough? I think a error message at compile time is more help full than Segmentation fault at run time. On UNIX-like operating systems, the available stack size is usually defined at run-time, and can often be tweaked per process. How much stack memory you can safely allocate and use depends on that, so it's hard to provide a compile time error.
Thanks for the explation.

on Mon Nov 24 2008, Andreas Klein <klein-AT-cage.UGent.be> wrote:
It seams that this resolves the bug. But I can not explain why. I tested the code with the intel compiler and it works fine for both implementations. So it seams that it is a gcc bug, that the first solution do not work. What happens here?
Looks like you should try a few different optimizer settings with GCC and then inspect the generated assembly code. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (6)
-
Andreas Klein
-
David Abrahams
-
Giovanni Piero Deretta
-
Jens Finkhäuser
-
John Bytheway
-
Niels Dekker - mail address until 2010-10-10