www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Error: constant false is not an lvalue

reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
void blah(out bool a = false){
 // blah blah blah
}

compile time use of blah results in error.

Am I doing anything wrong?
Aug 29 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 29 Aug 2009 20:15:55 -0400, Ellery Newcomer  
<ellery-newcomer utulsa.edu> wrote:

 void blah(out bool a = false){
  // blah blah blah
 }

 compile time use of blah results in error.

 Am I doing anything wrong?
out implies a reference. You can't have a reference to a manifest constant like that. If you want to ensure a is false at the beginning of the function do: void blah(out bool a) { a = false; // blah blah blah } -Steve
Aug 29 2009
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Steven Schveighoffer escribió:
 On Sat, 29 Aug 2009 20:15:55 -0400, Ellery Newcomer 
 <ellery-newcomer utulsa.edu> wrote:
 
 void blah(out bool a = false){
  // blah blah blah
 }

 compile time use of blah results in error.

 Am I doing anything wrong?
out implies a reference. You can't have a reference to a manifest constant like that. If you want to ensure a is false at the beginning of the function do: void blah(out bool a) { a = false; // blah blah blah } -Steve
Or just not write it, because "out" automatically initializes the value of the variable to it's default one, in the case of bool it's false.
Aug 29 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sun, Aug 30, 2009 at 12:24 AM, Ary Borenszweig<ary esperanto.org.ar> wro=
te:
 Steven Schveighoffer escribi=F3:
 On Sat, 29 Aug 2009 20:15:55 -0400, Ellery Newcomer
 <ellery-newcomer utulsa.edu> wrote:

 void blah(out bool a =3D false){
 =A0// blah blah blah
 }

 compile time use of blah results in error.

 Am I doing anything wrong?
out implies a reference. =A0You can't have a reference to a manifest constant like that. If you want to ensure a is false at the beginning of the function do: void blah(out bool a) { =A0a =3D false; =A0// blah blah blah } -Steve
Or just not write it, because "out" automatically initializes the value o=
f
 the variable to it's default one, in the case of bool it's false.
Although teeeeeeechnically speaking that would be illegal code. The D spec says that it's not legal to use the value of uninitialized variables. Default initialization is kind of a poor man's substitute for actual flow control which determines that. By relying on default initialization, you're relying on what is actually nonconformant behavior, and it could be broken in the future or by a smarter compiler. But we're getting really technical here ;)
Aug 29 2009
next sibling parent reply Rainer Deyke <rainerd eldwood.com> writes:
Jarrett Billingsley wrote:
 Although teeeeeeechnically speaking that would be illegal code. The D
 spec says that it's not legal to use the value of uninitialized
 variables. Default initialization is kind of a poor man's substitute
 for actual flow control which determines that. By relying on default
 initialization, you're relying on what is actually nonconformant
 behavior, and it could be broken in the future or by a smarter
 compiler.
No. This is an uninitialized variable in D: int i = void; This is an initialized variable in D: int i; A default-initialized variable is not in any way less initialized than any other initialized variable. Flow control can add two things to D. It can turn this: int i = <value>; or, equivalently, this: int i; into this: int i = void; whenever it is safe to do so. It can also turn this: int i = void; into an error message if it can prove that this is /not/ safe. It cannot ever alter the behavior of the following perfectly legal D function: int get_zero() { int i; return i; } -- Rainer Deyke - rainerd eldwood.com
Aug 30 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sun, Aug 30, 2009 at 5:34 AM, Rainer Deyke<rainerd eldwood.com> wrote:
 Jarrett Billingsley wrote:
 Although teeeeeeechnically speaking that would be illegal code. The D
 spec says that it's not legal to use the value of uninitialized
 variables. Default initialization is kind of a poor man's substitute
 for actual flow control which determines that. By relying on default
 initialization, you're relying on what is actually nonconformant
 behavior, and it could be broken in the future or by a smarter
 compiler.
No. =A0This is an uninitialized variable in D: =A0int i =3D void; This is an initialized variable in D: =A0int i; A default-initialized variable is not in any way less initialized than any other initialized variable.
"It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error." http://www.digitalmars.com/d/1.0/function.html I wouldn't be surprised if W himself has forgotten about this rule, since other parts of the spec make no mention of it, or seem to depend on the default-initialization of variables. "If the Initializer is void, however, the variable is not initialized. If its value is used before it is set, undefined program behavior will result." http://www.digitalmars.com/d/1.0/declaration.html But wait.. the previous statement said that it was an error to use a local without first assigning it a value. Meaning the code snippet given there (int x =3D void; writefln(x);) is invalid.
 It cannot ever alter the behavior of the following perfectly legal D
 function:

 =A0int get_zero() {
 =A0 =A0int i;
 =A0 =A0return i;
 =A0}
I interpret the first statement as saying that this isn't, and never has been, legal D, and that DMD simply has never checked for it. It's also illegal to declare variables that are never used, but you don't get an error for that either. As so many things in the D spec, this is unclear. The current behavior might actually be conformant to the first statement; it's just that the default initialization has made it all but pointless. The section(s) on default initialization of course do not mention how it interacts with the first rule. (Similar to how bools can't have any silly things like arithmetic operations performed on them (good!) but can be implicitly cast to almost every other basic type, meaning you can do it anyway (bad!).)
Aug 30 2009
next sibling parent grauzone <none example.net> writes:
 I wouldn't be surprised if W himself has forgotten about this rule,
 since other parts of the spec make no mention of it, or seem to depend
 on the default-initialization of variables.
 
 "If the Initializer is void, however, the variable is not initialized.
 If its value is used before it is set, undefined program behavior will
 result."
 http://www.digitalmars.com/d/1.0/declaration.html
And below that, there's even an example with local variables. I think what you were referring to is an outdated part of the specification, especially because "= void;" was added only recently. (Which also shows how worthless the specification is: not only incomplete, but full or inconsistencies and errors?) As to whether initializing variables by default or disallowing reading uninitialized values is better: I think it's very annoying, if the compiler tries to be smart, but then comes in to your way. Additionally, the result of the uninitialized value detection might end up being compiler specific, and that wouldn't be beautiful at all anymore. Actually, that case is very likely, since Walter would never rigorously define how exactly it should be done.
Aug 30 2009
prev sibling parent reply Rainer Deyke <rainerd eldwood.com> writes:
Jarrett Billingsley wrote:
 "It is an error to use a local variable without first assigning it a
 value. The implementation may not always be able to detect these
 cases. Other language compilers sometimes issue a warning for this,
 but since it is always a bug, it should be an error."
 http://www.digitalmars.com/d/1.0/function.html
Then the spec is wrong. Default initialization removes the need to explicitly assign a value to a variable in order to initialize it. The purpose of default initialization is not to find or reduce bugs, but to reduce the size of legal programs. For the purpose of reducing bugs, it would be better to always require explicit initialization. -- Rainer Deyke - rainerd eldwood.com
Aug 30 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sun, Aug 30, 2009 at 3:02 PM, Rainer Deyke<rainerd eldwood.com> wrote:
 The purpose of default initialization is not to find or reduce bugs, but
 to reduce the size of legal programs.
I'm wondering where the heck you got that justification.
Aug 30 2009
parent Rainer Deyke <rainerd eldwood.com> writes:
Jarrett Billingsley wrote:
 On Sun, Aug 30, 2009 at 3:02 PM, Rainer Deyke<rainerd eldwood.com> wrote:
 The purpose of default initialization is not to find or reduce bugs, but
 to reduce the size of legal programs.
I'm wondering where the heck you got that justification.
By looking at the actual effect of default initialization on the language. Imagine D without default initialization. This would be a syntax error: int i; Instead, you would have to write this: int i = 0; Clearly this imaginary variant of D is no more error-prone than D as it actually is. If anything, it is less error-prone, because it forces you to be explicit about how you want your variables to be initialized. It is, however, more verbose. -- Rainer Deyke - rainerd eldwood.com
Aug 30 2009
prev sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sun, Aug 30, 2009 at 3:14 PM, Jarrett
Billingsley<jarrett.billingsley gmail.com> wrote:
 On Sun, Aug 30, 2009 at 3:02 PM, Rainer Deyke<rainerd eldwood.com> wrote:
 The purpose of default initialization is not to find or reduce bugs, but
 to reduce the size of legal programs.
I'm wondering where the heck you got that justification.
Also, the spec says this: "Members are always initialized to the default initializer for their type, which is usually 0 for integer types and NAN for floating point types. This eliminates an entire class of obscure problems that come from neglecting to initialize a member in one of the constructors." http://www.digitalmars.com/d/1.0/class.html This suggests, to me, that default initialization _is_ - at least in Walter's mind - supposed to eliminate bugs.
Aug 30 2009
parent reply Rainer Deyke <rainerd eldwood.com> writes:
Jarrett Billingsley wrote:
 "Members are always initialized to the default initializer  for their
 type, which is usually 0 for integer types and NAN for floating point
 types. This eliminates an entire class of obscure problems that come
 from neglecting to initialize a member in one of the constructors."
 http://www.digitalmars.com/d/1.0/class.html
 
 This suggests, to me, that default initialization _is_ - at least in
 Walter's mind - supposed to eliminate bugs.
You (and possibly Walter) are comparing default initialization to uninitialized variables, which is a false dichotomy. I'm comparing default initialization to explicit initialization. -- Rainer Deyke - rainerd eldwood.com
Aug 30 2009
parent Don <nospam nospam.com> writes:
Rainer Deyke wrote:
 Jarrett Billingsley wrote:
 "Members are always initialized to the default initializer  for their
 type, which is usually 0 for integer types and NAN for floating point
 types. This eliminates an entire class of obscure problems that come
 from neglecting to initialize a member in one of the constructors."
 http://www.digitalmars.com/d/1.0/class.html

 This suggests, to me, that default initialization _is_ - at least in
 Walter's mind - supposed to eliminate bugs.
You (and possibly Walter) are comparing default initialization to uninitialized variables, which is a false dichotomy. I'm comparing default initialization to explicit initialization.
The whole point is to avoid uninitialized variables. Ideally, this would be done with explicit initialisation. The problem is that explicit initialisation is very painful to enforce. You can, however, enforce default initialisation -- it sometimes causes inefficiency, but it doesn't hurt the programmer much. And the =void allows you to avoid the efficiency hit, for the rare occassions when it matters. Default initialisation is a poor man's explicit initialisation.
Aug 31 2009
prev sibling parent reply grauzone <none example.net> writes:
Jarrett Billingsley wrote:
 On Sun, Aug 30, 2009 at 12:24 AM, Ary Borenszweig<ary esperanto.org.ar> wrote:
 Steven Schveighoffer escribió:
 On Sat, 29 Aug 2009 20:15:55 -0400, Ellery Newcomer
 <ellery-newcomer utulsa.edu> wrote:

 void blah(out bool a = false){
  // blah blah blah
 }

 compile time use of blah results in error.

 Am I doing anything wrong?
out implies a reference. You can't have a reference to a manifest constant like that. If you want to ensure a is false at the beginning of the function do: void blah(out bool a) { a = false; // blah blah blah } -Steve
Or just not write it, because "out" automatically initializes the value of the variable to it's default one, in the case of bool it's false.
Although teeeeeeechnically speaking that would be illegal code. The D spec says that it's not legal to use the value of uninitialized variables. Default initialization is kind of a poor man's substitute for actual flow control which determines that. By relying on default
Am I the only one, who likes the current behaviour, and finds it annoying to be forced by the compiler to initialize all variables?
 initialization, you're relying on what is actually nonconformant
 behavior, and it could be broken in the future or by a smarter
 compiler.
How is this nonconformant? Initialization is guaranteed by D.
 But we're getting really technical here ;)
Aug 30 2009
parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Sun, Aug 30, 2009 at 7:13 AM, grauzone<none example.net> wrote:
 Although teeeeeeechnically speaking that would be illegal code. The D
 spec says that it's not legal to use the value of uninitialized
 variables. Default initialization is kind of a poor man's substitute
 for actual flow control which determines that. By relying on default
Am I the only one, who likes the current behaviour, and finds it annoying to be forced by the compiler to initialize all variables?
The default initialization in D certainly hasn't helped me catch any bugs, only made them harder to spot. I'm a very big proponent of catching things at compile time.
 initialization, you're relying on what is actually nonconformant
 behavior, and it could be broken in the future or by a smarter
 compiler.
How is this nonconformant? Initialization is guaranteed by D.
This is where the spec is unclear, since why bother having the "can't access variables before assignment" rule if the "all variables are default-initialized" rule all but removes the need for it?
Aug 30 2009
prev sibling parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
Steven Schveighoffer wrote:
 On Sat, 29 Aug 2009 20:15:55 -0400, Ellery Newcomer
 <ellery-newcomer utulsa.edu> wrote:
 
 void blah(out bool a = false){
  // blah blah blah
 }

 compile time use of blah results in error.

 Am I doing anything wrong?
out implies a reference. You can't have a reference to a manifest constant like that.
Are you saying a parameter like out type a = b implies the function assigns b's memory location to a?
Aug 30 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 30 Aug 2009 11:25:59 -0400, Ellery Newcomer  
<ellery-newcomer utulsa.edu> wrote:

 Steven Schveighoffer wrote:
 On Sat, 29 Aug 2009 20:15:55 -0400, Ellery Newcomer
 <ellery-newcomer utulsa.edu> wrote:

 void blah(out bool a = false){
  // blah blah blah
 }

 compile time use of blah results in error.

 Am I doing anything wrong?
out implies a reference. You can't have a reference to a manifest constant like that.
Are you saying a parameter like out type a = b implies the function assigns b's memory location to a?
In a parameter list? What this does: void foo(int i = 4); is allow you to call foo with no arguments, and i is initialized to 4. Now, let's say foo is written like this: void foo(ref int i = 4); What is i referencing when you call: foo(); ??? -Steve
Aug 31 2009
parent reply "Manfred_Nowak" <svv1999 hotmail.com> writes:
Steven Schveighoffer wrote:

 What is i referencing when you call:
   foo();
Is this an argument for making int j; void foo(ref int i = &j); foo(): legal D? -manfred
Aug 31 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 31 Aug 2009 13:00:34 -0400, Manfred_Nowak <svv1999 hotmail.com>  
wrote:

 Steven Schveighoffer wrote:

 What is i referencing when you call:
   foo();
Is this an argument for making int j; void foo(ref int i = &j); foo(): legal D?
No, I'm just trying to explain why having a default value for a ref arg that is a manifest constant makes no sense. It's possible that something like what you wrote could work (although I'd write it foo(ref int i = j)). -Steve
Aug 31 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 31 Aug 2009 14:55:43 -0400, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 It's possible that something like what you wrote could work (although  
 I'd write it foo(ref int i = j)).
In fact, it does work, in D1 no less. # cat testme.d import tango.io.Stdout; int j; void foo(ref int i = j) { i++; } void main() { int i = 4; foo(); foo(i); Stdout(i, j).newline; } # dmd testme.d # ./testme 5, 1 -Steve
Aug 31 2009
parent "Manfred_Nowak" <svv1999 hotmail.com> writes:
Steven Schveighoffer wrote:

 In fact, it does work, in D1 no less.
thx ... and another example, that initializing with int.max would serve Walter's intentions better. -manfred
Aug 31 2009