www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Yet another "static" confusion

reply Lubos Pintes <lubos.pintes gmail.com> writes:
Hi,
I want to allocate a buffer which I use in a function which reads data 
from socket.
So I did as a first line in that function:
static char[] buffer=new char[4096];

The compiler (2.062) complained that it cannot evaluate new char[] at 
compile time.
I Then tried to move the declaration before function, the same thing 
happened. Allocating statically sized array bloats the executable.
My idea is to return only a slice of array if less than 4K data was read 
and prevent new allocation on every read.

So what I am doing wrong or is this not possible?
Thank.
Feb 20 2013
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 20 February 2013 at 08:03:48 UTC, Lubos Pintes 
wrote:
 Hi,
 I want to allocate a buffer which I use in a function which 
 reads data from socket.
 So I did as a first line in that function:
 static char[] buffer=new char[4096];

 The compiler (2.062) complained that it cannot evaluate new 
 char[] at compile time.
 I Then tried to move the declaration before function, the same 
 thing happened. Allocating statically sized array bloats the 
 executable.
 My idea is to return only a slice of array if less than 4K data 
 was read and prevent new allocation on every read.

 So what I am doing wrong or is this not possible?
 Thank.
In D (and unlike C++), anything static MUST have an initial state that is statically evaluable. "new char[4096]" is a run-time call, so it cannot be done. The truth is that this actually isn't much different from C++, which hides an invisible "is_initialized" bool somewhere to make it work. You can try to run-time initialize your buffer the module constructor, for example. Or just create an accessor to get an initialized buffer: void getBuffer() safe nothrow { static char[] buffer; if (buffer.empty) buffer = new char[4096]; return buffer; }
Feb 20 2013
parent reply Lubos Pintes <lubos.pintes gmail.com> writes:
Ok thank you. I see now.
One unrelated question: Why the safe attribute has the at-sign, while 
nothrow doesn't?
Dňa 20. 2. 2013 11:19 monarch_dodra  wrote / napísal(a):
 On Wednesday, 20 February 2013 at 08:03:48 UTC, Lubos Pintes wrote:
 Hi,
 I want to allocate a buffer which I use in a function which reads data
 from socket.
 So I did as a first line in that function:
 static char[] buffer=new char[4096];

 The compiler (2.062) complained that it cannot evaluate new char[] at
 compile time.
 I Then tried to move the declaration before function, the same thing
 happened. Allocating statically sized array bloats the executable.
 My idea is to return only a slice of array if less than 4K data was
 read and prevent new allocation on every read.

 So what I am doing wrong or is this not possible?
 Thank.
In D (and unlike C++), anything static MUST have an initial state that is statically evaluable. "new char[4096]" is a run-time call, so it cannot be done. The truth is that this actually isn't much different from C++, which hides an invisible "is_initialized" bool somewhere to make it work. You can try to run-time initialize your buffer the module constructor, for example. Or just create an accessor to get an initialized buffer: void getBuffer() safe nothrow { static char[] buffer; if (buffer.empty) buffer = new char[4096]; return buffer; }
Feb 20 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Lubos Pintes:

 Why the safe attribute has the at-sign, while nothrow doesn't?
Historical accidents... There is no rhyme & reason in that. Bye, bearophile
Feb 20 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Lubos Pintes:

 Allocating statically sized array bloats the executable.
Because char.init is not '\0'. Try to initialize it with zero: char[10_000] a = '\0'; void main() {} Bye, bearophile
Feb 20 2013
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 20 Feb 2013 03:03:49 -0500, Lubos Pintes <lubos.pintes gmail.com>  
wrote:

 Hi,
 I want to allocate a buffer which I use in a function which reads data  
 from socket.
 So I did as a first line in that function:
 static char[] buffer=new char[4096];

 The compiler (2.062) complained that it cannot evaluate new char[] at  
 compile time.
 I Then tried to move the declaration before function, the same thing  
 happened. Allocating statically sized array bloats the executable.
 My idea is to return only a slice of array if less than 4K data was read  
 and prevent new allocation on every read.

 So what I am doing wrong or is this not possible?
 Thank.
What about a fixed sized array? That won't even incur a heap allocation cost, and makes the function reentrant: char[4096] buffer = void; // use = void to ensure the compiler doesn't initialize the buffer to all 0xff -Steve
Feb 20 2013