www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Uninitialized variables

reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
http://www.digitalmars.com/d/memory.html

Defines as ways to get memory on the stack, which is uninitialized, the 
following:

byte[] buffer = (cast(byte*)std.c.stdlib.alloca(1024))[0 .. 1024];

Which is obviously a little unfriendly, but usable.  It defines no 
method to retrieve uninitialized variables (e.g. an int), and etc.  Of 
course, it may not be common to need this, really, but it's a useful 
thing to have if you know you will be setting the variable later anyway.

I would like to suggest the following syntax as an alternative:

uninitialized byte[1024] buffer;

While the keyword "uninitialized" is long, it is also not commonly used 
and still shorter than the alloca line above.  This would also allow:

uninitialized int i;
byte[] data = new uninitialized byte[1024];

In short, it could be used after new or proceeding the type - on the 
stack or off.  However, for the purposes of garbage collection and etc, 
some limits would obviously have to be imposed:

uninitialized int* p;
uninitialized Class c;
uninitialized byte[] array;
uninitialized st_something s;
uninitialized int i = 5;

test.d(1): pointers, structs, and classes cannot be uninitialized.
test.d(2): pointers, structs, and classes cannot be uninitialized.
test.d(3): dynamic arrays cannot be uninitialized; try = new uninitialized.
test.d(4): pointers, structs, and classes cannot be uninitialized.
test.d(5): uninitialized variable was initialized.

Or similar.  The restriction on structs only because they could have 
pointers or etc. in them, and I didn't want to ask for the compiler to 
deduce if the struct was able to be uninitialized.

Does such a syntax seem desirable, if verbose?  Or is it just 
"syntactical sugar"?

-[Unknown]
Jun 06 2005
next sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message 
news:d82cnj$un8$1 digitaldaemon.com...
 http://www.digitalmars.com/d/memory.html

 Defines as ways to get memory on the stack, which is uninitialized, the 
 following:

 byte[] buffer = (cast(byte*)std.c.stdlib.alloca(1024))[0 .. 1024];

 Which is obviously a little unfriendly, but usable.

Note the package name can be dropped to make it slightly more usable byte[] buffer = (cast(byte*)alloca(1024))[0 .. 1024];
 It defines no method to retrieve uninitialized variables (e.g. an int), 
 and etc.  Of course, it may not be common to need this, really, but it's a 
 useful thing to have if you know you will be setting the variable later 
 anyway.

 I would like to suggest the following syntax as an alternative:

 uninitialized byte[1024] buffer;

At one point it was suggested to use a "void initializer": byte[1024] buffer = void; which has the advantage of not requiring a new keyword.
 While the keyword "uninitialized" is long, it is also not commonly used 
 and still shorter than the alloca line above.  This would also allow:

 uninitialized int i;
 byte[] data = new uninitialized byte[1024];

The above void initializer syntax wouldn't work in this case - at least not obviously. Perhaps a variation would be that an array of void is left uninitialized. For example byte[] data = cast(byte[])(new void[1024]); I'm not sure what currently happens when you try to allocate an array of voids.
 In short, it could be used after new or proceeding the type - on the stack 
 or off.  However, for the purposes of garbage collection and etc, some 
 limits would obviously have to be imposed:

 uninitialized int* p;
 uninitialized Class c;
 uninitialized byte[] array;
 uninitialized st_something s;
 uninitialized int i = 5;

 test.d(1): pointers, structs, and classes cannot be uninitialized.
 test.d(2): pointers, structs, and classes cannot be uninitialized.
 test.d(3): dynamic arrays cannot be uninitialized; try = new 
 uninitialized.
 test.d(4): pointers, structs, and classes cannot be uninitialized.
 test.d(5): uninitialized variable was initialized.

It would be nice to invent a syntax that doesn't require any special cases or ambiguity rules.
 Or similar.  The restriction on structs only because they could have 
 pointers or etc. in them, and I didn't want to ask for the compiler to 
 deduce if the struct was able to be uninitialized.

 Does such a syntax seem desirable, if verbose?  Or is it just "syntactical 
 sugar"?

 -[Unknown] 

Jun 06 2005
parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
But even with the void syntax, you have:

int* p = void;

Which must be an error as well, to my understanding, so that a garbage 
collector won't get confused, no?  Or maybe I'm just making things up? 
If that's not true, uninitialized doesn't need the rules either.

Anyway, benefits of uninitialized are that it:
   - doesn't look like initialization, since it's not.
   - could be defined as optional (ignoreable) by implementation (void 
could too, I guess.)
   - doesn't abuse a type as a value.

-[Unknown]


 "Unknown W. Brackets" <unknown simplemachines.org> wrote in message 
 news:d82cnj$un8$1 digitaldaemon.com...
 
http://www.digitalmars.com/d/memory.html

Defines as ways to get memory on the stack, which is uninitialized, the 
following:

byte[] buffer = (cast(byte*)std.c.stdlib.alloca(1024))[0 .. 1024];

Which is obviously a little unfriendly, but usable.

Note the package name can be dropped to make it slightly more usable byte[] buffer = (cast(byte*)alloca(1024))[0 .. 1024];
It defines no method to retrieve uninitialized variables (e.g. an int), 
and etc.  Of course, it may not be common to need this, really, but it's a 
useful thing to have if you know you will be setting the variable later 
anyway.

I would like to suggest the following syntax as an alternative:

uninitialized byte[1024] buffer;

At one point it was suggested to use a "void initializer": byte[1024] buffer = void; which has the advantage of not requiring a new keyword.
While the keyword "uninitialized" is long, it is also not commonly used 
and still shorter than the alloca line above.  This would also allow:

uninitialized int i;
byte[] data = new uninitialized byte[1024];

The above void initializer syntax wouldn't work in this case - at least not obviously. Perhaps a variation would be that an array of void is left uninitialized. For example byte[] data = cast(byte[])(new void[1024]); I'm not sure what currently happens when you try to allocate an array of voids.
In short, it could be used after new or proceeding the type - on the stack 
or off.  However, for the purposes of garbage collection and etc, some 
limits would obviously have to be imposed:

uninitialized int* p;
uninitialized Class c;
uninitialized byte[] array;
uninitialized st_something s;
uninitialized int i = 5;

test.d(1): pointers, structs, and classes cannot be uninitialized.
test.d(2): pointers, structs, and classes cannot be uninitialized.
test.d(3): dynamic arrays cannot be uninitialized; try = new 
uninitialized.
test.d(4): pointers, structs, and classes cannot be uninitialized.
test.d(5): uninitialized variable was initialized.

It would be nice to invent a syntax that doesn't require any special cases or ambiguity rules.
Or similar.  The restriction on structs only because they could have 
pointers or etc. in them, and I didn't want to ask for the compiler to 
deduce if the struct was able to be uninitialized.

Does such a syntax seem desirable, if verbose?  Or is it just "syntactical 
sugar"?

-[Unknown] 


Jun 06 2005
parent reply Ben Hinkle <Ben_member pathlink.com> writes:
In article <d82e24$vs0$1 digitaldaemon.com>, Unknown W. Brackets says...
But even with the void syntax, you have:

int* p = void;

Which must be an error as well, to my understanding, so that a garbage 
collector won't get confused, no?  Or maybe I'm just making things up? 
If that's not true, uninitialized doesn't need the rules either.

I was assuming that those cases wouldn't error. The two proposals (in the area of initializers) are equivalent uninitialized foo bar; <-> foo bar = void; with the one exception that foo bar = void avoids the ambiguous situation uninitialized foo bar = 5;
Anyway, benefits of uninitialized are that it:
   - doesn't look like initialization, since it's not.

with initialization. To me it's obvious which of the following are uninitialized and which aren't int x = 10, y = void, z = 20;
   - could be defined as optional (ignoreable) by implementation (void 
could too, I guess.)

   - doesn't abuse a type as a value.

To me the plus/minus is 1) =void avoids the ambiguous case where both uninitialized and an initalizer are specified 2) =void does not directly address how to allocate uninitialized dynamic GC memory
Jun 06 2005
parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
Fair enough.  I still think that it makes just as much sense as:

int* p = int;

Or in other words, none.  I just can't think of anywhere a type, even 
void, is used as a value.  It's contradictory to me.

-[Unknown]


 In article <d82e24$vs0$1 digitaldaemon.com>, Unknown W. Brackets says...
 
But even with the void syntax, you have:

int* p = void;

Which must be an error as well, to my understanding, so that a garbage 
collector won't get confused, no?  Or maybe I'm just making things up? 
If that's not true, uninitialized doesn't need the rules either.

I was assuming that those cases wouldn't error. The two proposals (in the area of initializers) are equivalent uninitialized foo bar; <-> foo bar = void; with the one exception that foo bar = void avoids the ambiguous situation uninitialized foo bar = 5;
Anyway, benefits of uninitialized are that it:
  - doesn't look like initialization, since it's not.

actually I would say that indicating uninitialized state is intimately involved with initialization. To me it's obvious which of the following are uninitialized and which aren't int x = 10, y = void, z = 20;
  - could be defined as optional (ignoreable) by implementation (void 
could too, I guess.)

agreed. the two are the same.
  - doesn't abuse a type as a value.

one person's "natural extension" is another's "abuse"... To me the plus/minus is 1) =void avoids the ambiguous case where both uninitialized and an initalizer are specified 2) =void does not directly address how to allocate uninitialized dynamic GC memory

Jun 06 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 06 Jun 2005 17:02:42 -0700, Unknown W. Brackets wrote:

 Fair enough.  I still think that it makes just as much sense as:
 
 int* p = int;
 
 Or in other words, none.  I just can't think of anywhere a type, even 
 void, is used as a value.  It's contradictory to me.

Well that's a valid point of view too. To me, "void" is just a word, like "static". It can have various meanings in the language depending on how its used. Just like in English, "void" has various meanings - "empty", "no longer usable", ... Though my preference is for a new keyword that is self-documenting. So "uninitialized", "raw", and "unformatted" all seem acceptable. -- Derek Melbourne, Australia 7/06/2005 10:55:32 AM
Jun 06 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 7 Jun 2005 11:07:34 +1000, Derek Parnell <derek psych.ward> wrote:
 On Mon, 06 Jun 2005 17:02:42 -0700, Unknown W. Brackets wrote:

 Fair enough.  I still think that it makes just as much sense as:

 int* p = int;

 Or in other words, none.  I just can't think of anywhere a type, even
 void, is used as a value.  It's contradictory to me.

Well that's a valid point of view too. To me, "void" is just a word, like "static". It can have various meanings in the language depending on how its used. Just like in English, "void" has various meanings - "empty", "no longer usable", ... Though my preference is for a new keyword that is self-documenting. So "uninitialized", "raw", and "unformatted" all seem acceptable.

"noinit" Regan
Jun 06 2005
prev sibling next sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 06 Jun 2005 13:47:08 -0700, Unknown W. Brackets  
<unknown simplemachines.org> wrote:
 In short, it could be used after new or proceeding the type - on the  
 stack or off.  However, for the purposes of garbage collection and etc,  
 some limits would obviously have to be imposed:

 uninitialized int* p;
 uninitialized Class c;
 uninitialized byte[] array;
 uninitialized st_something s;
 uninitialized int i = 5;

 test.d(1): pointers, structs, and classes cannot be uninitialized.
 test.d(2): pointers, structs, and classes cannot be uninitialized.
 test.d(3): dynamic arrays cannot be uninitialized; try = new  
 uninitialized.
 test.d(4): pointers, structs, and classes cannot be uninitialized.
 test.d(5): uninitialized variable was initialized.

 Or similar.  The restriction on structs only because they could have  
 pointers or etc. in them, and I didn't want to ask for the compiler to  
 deduce if the struct was able to be uninitialized.

Quick question... I didn't think the GC treated a pointer any different to an int, in that if either block of memory (the one containing the pointer or int) contained a value which could be a memory address, it stopped that memory address from being considered unreferenced and thus free to be free'd. Am I wrong? Regan
Jun 06 2005
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 06 Jun 2005 13:47:08 -0700, Unknown W. Brackets  
<unknown simplemachines.org> wrote:
 http://www.digitalmars.com/d/memory.html

 Defines as ways to get memory on the stack, which is uninitialized, the  
 following:

 byte[] buffer = (cast(byte*)std.c.stdlib.alloca(1024))[0 .. 1024];

 Which is obviously a little unfriendly, but usable.  It defines no  
 method to retrieve uninitialized variables (e.g. an int), and etc.  Of  
 course, it may not be common to need this, really, but it's a useful  
 thing to have if you know you will be setting the variable later anyway.

 I would like to suggest the following syntax as an alternative:

 uninitialized byte[1024] buffer;

 While the keyword "uninitialized" is long, it is also not commonly used  
 and still shorter than the alloca line above.  This would also allow:

 uninitialized int i;
 byte[] data = new uninitialized byte[1024];

 In short, it could be used after new or proceeding the type - on the  
 stack or off.  However, for the purposes of garbage collection and etc,  
 some limits would obviously have to be imposed:

 uninitialized int* p;
 uninitialized Class c;
 uninitialized byte[] array;
 uninitialized st_something s;
 uninitialized int i = 5;

 test.d(1): pointers, structs, and classes cannot be uninitialized.
 test.d(2): pointers, structs, and classes cannot be uninitialized.
 test.d(3): dynamic arrays cannot be uninitialized; try = new  
 uninitialized.
 test.d(4): pointers, structs, and classes cannot be uninitialized.
 test.d(5): uninitialized variable was initialized.

 Or similar.  The restriction on structs only because they could have  
 pointers or etc. in them, and I didn't want to ask for the compiler to  
 deduce if the struct was able to be uninitialized.

 Does such a syntax seem desirable, if verbose?  Or is it just  
 "syntactical sugar"?

My take... Types on which it makes little or no sense to use 'non-initialisation': char[] dynamic; //all dynamic arrays, unless assigned with 'new'. int i; //and other small stack based types. Class ref; //class references Types on which it is useful: char[100] static; //all static arrays. char[] dynamic_assign = new char[1000]; //all dynamic arrays, assigned with new. Basically it seems when a large block of memory is allocated, you want to choose not to initialise it. I'd suggest the keyword 'raw', and I'd suggest it's usage be: raw char[100] static; //as a type-modifier char[] dynamic_assign = raw char[1000]; //as replacement for new? or perhaps (if you dislike the 'abuse' of the type modifier 'raw' as a replacement for 'new') char[] dynamic_assign = new raw char[1000]; //as type-modifier So, raw would mean uncooked or 0xd34db33f if you will ;) Regan
Jun 06 2005
parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
The problem with raw is it would commonly be used in programs already as 
a variable name or similar - at least, I've seen it more than a couple 
times.  Find me a program that uses "uninitialized"... sure, there may 
very well be some, but probably not many.

If you want an uninitialized stack variable, what's wrong with that? 
Sure, it doesn't save much time - but if the function is being called 
1000 times a second, it might be worth it.

I, probably wrongly, assumed that the gc or more likely other potential 
gc implementations might recognize all pointer types.  If this is 
incorrect, you still have classes and dynamic arrays.

-[Unknown]


 My take...
 
 Types on which it makes little or no sense to use 'non-initialisation':
 char[] dynamic; //all dynamic arrays, unless assigned with 'new'.
 int i; //and other small stack based types.
 Class ref; //class references
 
 Types on which it is useful:
 char[100] static; //all static arrays.
 char[] dynamic_assign = new char[1000]; //all dynamic arrays, assigned  
 with new.
 
 Basically it seems when a large block of memory is allocated, you want 
 to  choose not to initialise it. I'd suggest the keyword 'raw', and I'd  
 suggest it's usage be:
 
 raw char[100] static; //as a type-modifier
 char[] dynamic_assign = raw char[1000]; //as replacement for new?
 
 or perhaps (if you dislike the 'abuse' of the type modifier 'raw' as a  
 replacement for 'new')
 
 char[] dynamic_assign = new raw char[1000]; //as type-modifier
 
 So, raw would mean uncooked or 0xd34db33f if you will ;)
 
 Regan

Jun 06 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 06 Jun 2005 17:00:43 -0700, Unknown W. Brackets  
<unknown simplemachines.org> wrote:
 The problem with raw is it would commonly be used in programs already as  
 a variable name or similar - at least, I've seen it more than a couple  
 times.  Find me a program that uses "uninitialized"... sure, there may  
 very well be some, but probably not many.

True. However, I'd prefer the *best* word, rather than the one with the least conflicts, at least at this stage in D's development. That said, 'raw' may not be the *best* word. I prefer 'noinit' now ;)
 If you want an uninitialized stack variable, what's wrong with that?  
 Sure, it doesn't save much time - but if the function is being called  
 1000 times a second, it might be worth it.

True, maybe in those circumstances. It also makes me wonder what effect inlining has on variable initialisations, if any, and how this might tie into that. After all, you'd want your function being called 1000 times a second to be inlined.
 I, probably wrongly, assumed that the gc or more likely other potential  
 gc implementations might recognize all pointer types.  If this is  
 incorrect, you still have classes and dynamic arrays.

I think you're correct, in that we might have one in the future that can tell. The current one, IIRC, cannot. Regan
 My take...
  Types on which it makes little or no sense to use 'non-initialisation':
 char[] dynamic; //all dynamic arrays, unless assigned with 'new'.
 int i; //and other small stack based types.
 Class ref; //class references
  Types on which it is useful:
 char[100] static; //all static arrays.
 char[] dynamic_assign = new char[1000]; //all dynamic arrays, assigned   
 with new.
  Basically it seems when a large block of memory is allocated, you want  
 to  choose not to initialise it. I'd suggest the keyword 'raw', and  
 I'd  suggest it's usage be:
  raw char[100] static; //as a type-modifier
 char[] dynamic_assign = raw char[1000]; //as replacement for new?
  or perhaps (if you dislike the 'abuse' of the type modifier 'raw' as  
 a  replacement for 'new')
  char[] dynamic_assign = new raw char[1000]; //as type-modifier
  So, raw would mean uncooked or 0xd34db33f if you will ;)
  Regan


Jun 06 2005