Jump to page: 1 2 3
Thread overview
Re: Docs: Section on local variables
Apr 20, 2012
Jonathan M Davis
Apr 20, 2012
bearophile
Apr 21, 2012
Jakob Ovrum
Apr 21, 2012
Andrej Mitrovic
Apr 21, 2012
Jakob Ovrum
Apr 21, 2012
Andrej Mitrovic
Apr 21, 2012
Nick Sabalausky
Apr 21, 2012
Andrej Mitrovic
Apr 22, 2012
Nick Sabalausky
Apr 21, 2012
Jonathan M Davis
Apr 21, 2012
Jakob Ovrum
Apr 21, 2012
Andrej Mitrovic
Apr 21, 2012
Jonathan M Davis
Apr 21, 2012
Nick Sabalausky
Apr 21, 2012
Jonathan M Davis
Apr 21, 2012
Nick Sabalausky
Apr 21, 2012
bearophile
Apr 21, 2012
Jakob Ovrum
Apr 21, 2012
Timon Gehr
Apr 22, 2012
Nick Sabalausky
Apr 21, 2012
Famous
Apr 21, 2012
Kagamin
Apr 21, 2012
Kagamin
Apr 21, 2012
Kagamin
Apr 21, 2012
H. S. Teoh
Apr 22, 2012
Nick Sabalausky
Apr 21, 2012
Jonathan M Davis
April 20, 2012
On Friday, April 20, 2012 03:22:43 Andrej Mitrovic wrote:
> Can we remove this section from the D docs, in the functions section? :
> 
> "
> Local Variables
> 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.

There's no way that this is ever going to be the case. There are cases where you can't use a variable's initial value. For example,

T var;
if(cond)
{
 //do a bunch of stuff
 var = something;
}
else
 vare = somethingElse;

So, it can only really be initialized to a default value - which already happens automatically. And there's plenty of code out there that relies on the default values that variables are given and doesn't bother initializing them.

Personally, I think that variables should always be initialized rather than relying on the default value (even if you're initilazing them to the default value) except in cases where you're specifically deferring initialization and would use = void if you wanted the extra efficiency (though it's generally better not to use = void unless you need it, since there's definite risk associated with it). But there's no way that the compiler is going to enforce that, and if it did, it would require that you initialize the variable in the above example even though the compiler already does.

It seems to me that there are two approaches for the language to take:

1. Force all variables to be explicitly initialized, even if they don't really need to be (but the compiler can't always tell for sure). Java and C# take this approach.

2. Default-initialize everything. D does this.

The above doc excerpt is basically requiring #1 even though D already does #2. If that's the case, why have #2 at all? So, I'd vote to remove that from the docs. It isn't true, and I don't expect it to over be true.

> It is an error to declare a local variable that is never referred to.
> Dead variables, like anachronistic dead code, are just a source of
> confusion for maintenance programmers.
> "

This could done, but it's definitely _not_ a warning or error right now. It's also not ever going to be an error AFAIK, so I'd definitely vote to remove it from the docs. I know that Walter's already against making unused parameters either warnings or errors. It's a slightly different situation with local variables, since you don't have the overriding issue that can create unused variables with function parameters, but I also don't think that it's enough a problem to warrant an error. At most, it would be a warning, which wouldn't need to be mentioned in the docs IMHO. So, I definitely be for removing it as well.

- Jonathan M Davis
April 20, 2012
Jonathan M Davis:

>> Local Variables
>> It is an error to use a local variable without first assigning it a value.
>>...
> There's no way that this is ever going to be the case. There are cases where
> you can't use a variable's initial value. For example,
>
> T var;
> if(cond)
> {
>  //do a bunch of stuff
>  var = something;
> }
> else
>  vare = somethingElse;

I think "use a local variable" doesn't mean "assign it immediately", it means essentially "reading it before writing it". So that code is correct.


> This could done, but it's definitely _not_ a warning or error right now. It's
> also not ever going to be an error AFAIK, so I'd definitely vote to remove it from the docs.

I think in Go unused local variables are an error.
If you go here and you try to add "x := 1" inside the main you receive an error, not a warning:
http://golang.org/#
And I think today Go programmers survive well enough to such strictness.

Bye,
bearophile
April 21, 2012
On Friday, 20 April 2012 at 18:40:46 UTC, Jonathan M Davis wrote:

> But there's no way that the compiler is going to enforce
> that, and if it did, it would require that you initialize the variable in the
> above example even though the compiler already does.

Why can't the compiler enforce it? C# and Java compilers can do it just fine.

> It seems to me that there are two approaches for the language to take:
>
> 1. Force all variables to be explicitly initialized, even if they don't really
> need to be (but the compiler can't always tell for sure). Java and C# take
> this approach.

Java and C# do not do that. They just enforce that local variables have to be written to at least once before being read. The control flow graph takes care of correctly determining whether a variable has been initialized.
April 21, 2012
On 4/21/12, Jakob Ovrum <jakobovrum@gmail.com> wrote:
> The control flow graph takes care of correctly determining whether a variable has been initialized.

It is initialized. .init takes care of that.
April 21, 2012
On Saturday, 21 April 2012 at 01:14:27 UTC, Andrej Mitrovic wrote:
> On 4/21/12, Jakob Ovrum <jakobovrum@gmail.com> wrote:
>> The control flow graph takes care of correctly determining
>> whether a variable has been initialized.
>
> It is initialized. .init takes care of that.

Read again; there is no .init in Java or C# :)
April 21, 2012
On Saturday, April 21, 2012 02:54:25 Jakob Ovrum wrote:
> On Friday, 20 April 2012 at 18:40:46 UTC, Jonathan M Davis wrote:
> > But there's no way that the compiler is going to enforce
> > that, and if it did, it would require that you initialize the
> > variable in the
> > above example even though the compiler already does.
> 
> Why can't the compiler enforce it? C# and Java compilers can do it just fine.

I didn't say that it couldn't. I said that there was no way that it would. It would break a lot of code, and it goes completely against D's current approach of default-initialization everything. I'd be shocked if Walter agreed to making the compiler give an error for variables which aren't either assigned to or directly initialized before they're used. init solves the problem already. There's no need to do what C# and Java do on top of that.

> > It seems to me that there are two approaches for the language to take:
> > 
> > 1. Force all variables to be explicitly initialized, even if
> > they don't really
> > need to be (but the compiler can't always tell for sure). Java
> > and C# take
> > this approach.
> 
> Java and C# do not do that. They just enforce that local variables have to be written to at least once before being read.

Okay. I should have said that Java and C# require that a variable be written to before being used. Regardless, they take the approach of requiring that a variable be initialized/assigned a value rather than letting it be garbage (like C/C++) or initializing it to a default value (like D).

> The control flow graph takes care of correctly determining whether a variable has been initialized.

And Walter seems to hate flow analysis like the plague (due to its increased complexity IIRC). _Very_ little in D requires or does flow analysis.

- Jonathan M Davis
April 21, 2012
On 4/21/12, Jakob Ovrum <jakobovrum@gmail.com> wrote:
> Read again; there is no .init in Java or C# :)

Right, but we have it so we're set.

I bet if instead of opening this thread and if I just made a pull that removed that section in the docs most people wouldn't even notice it was gone. I don't remember the last time anyone complained about (or made a thread about) the lack of warnings for uninitialized variables, but suddenly it's controversial to remove it from the docs. :)
April 21, 2012
On Saturday, 21 April 2012 at 01:31:45 UTC, Jonathan M Davis wrote:
> Okay. I should have said that Java and C# require that a variable be written
> to before being used. Regardless, they take the approach of requiring that a
> variable be initialized/assigned a value rather than letting it be garbage
> (like C/C++) or initializing it to a default value (like D).

It solves only part of the problem. If a simple, unconditional default-initialization was an objectively superior solution, nobody would bother implementing control flow graphs.

When "int x;" and "int x = 0;" are semantically identical, the intention of the programmer isn't clear in the case of "int x;" (talking about local variables only, of course). Is the default value relied upon intentionally in the program? What if it unintentionally reads the default value? The default value is more helpful than garbage when debugging (especially for non-integer types), but with a proper implementation, errors like these can be caught at compile-time.

You could introduce coding conventions in your project to manage the issue, but then we're in faith-based programming territory.

>
>> The control flow graph takes care of correctly determining
>> whether a variable has been initialized.
>
> And Walter seems to hate flow analysis like the plague (due to its increased
> complexity IIRC).

It's well-trodden area, it doesn't have to be difficult.

>_Very_ little in D requires or does flow
> analysis.

And D is worse off because of it.
April 21, 2012
On 4/21/12, Jakob Ovrum <jakobovrum@gmail.com> wrote:
> If a simple, unconditional
> default-initialization was an objectively superior solution,
> nobody would bother implementing control flow graphs.

If x then y.

If warnings were superior then nobody would write shit like this:

#pragma(push)
#pragma warning(disable: 4701)
int x;
#pragma(pop)

Or even better when someone furiously adds a comment:
....
int x = 0;  // silence stupid gcc warning #@!*&%
x = ...

I've seen both of these used in popular C++ codebases.

So, ultimately we can rely on .init in D, and we already do. If someone missed warnings in D for locals initialized to .init then how come nobody ever complains about them?
April 21, 2012
"Andrej Mitrovic" <andrej.mitrovich@gmail.com> wrote in message news:mailman.2002.1334970925.4860.digitalmars-d@puremagic.com...
> On 4/21/12, Jakob Ovrum <jakobovrum@gmail.com> wrote:
>> The control flow graph takes care of correctly determining whether a variable has been initialized.
>
> It is initialized. .init takes care of that.

Yes, it's initialized to .init by default. But .init may not be what the programmer intended it to be initialized to. You've never forgotten to initialize something that wasn't supposed to be T.init?

When an expicit initializer is left out by accident, C# knows. D doesn't know.


« First   ‹ Prev
1 2 3