Walter Bright:

But it is not uninitialized. All out parameters are default initialized to their .init value.<
I don't agree with this opinion, as they *are* initialized.<

The documentation of Microsoft SAL2, several discussions, and some other things I've read tell me that if you want your compiler to catch some of your bugs statically (and optimize well) it needs to be strict. Being strict often means following a narrow semantics that forbids some rarely useful but correct programs, and allow only the large percentage of the remaining ones.

D has more built-in annotations that most other languages I know, and I like to use them a lot, but their return of investiment is not always very high. If an annotation allows to catch some bugs or allows the compiler to optimize better, or it helps the programmer reason in a simpler way about the code, then the annotation is giving something back.

I remember discussions about D "pure" not being very useful to the GDC back-end to optimize the code.

Back to the topic of the "out" arguments discussed here, it's true that the out argument gets initialized at function entry, so the current implementation of out is correct. But we should look at the sum of advantages and disadvantages. If I write a function with an out argument I may want to initialize it inside the function or I may want just the default initialization, currently both the following functions are allowed and usable in D:

void foo(out int x) {}
void bar(out int x) { x = 10; }

How much often do I need to write a function like foo? I think it's uncommon. Most times I add an "out" argument I want to write a function like bar that puts something inside x.

On the other hand sometimes I want to write a function like bar, but by mistake I end writing a function like foo, I forget to initialize an out argument inside the function. I don't know how common is this kind of bug (because out arguments are quite rare in my code, so I don't have much statistic), but it can be costly.

So is it better to catch the bugs caused by the programmer forgetting to inizialize an out argument, and forbid the functions like foo (that I think are not common), or is it better to allow functions like foo because they are sufficiently common to justify the reduced strictness of the out argument semantics?

Looking at the cost-benefit analysis, I am willing to restrict the language and disallow functions like foo because they are not common in my code, and in turn catch statically some bugs where I miss to initialize the out argument manually (despite I don't know how much common such bugs are. This makes such analysis based on fried air, so if you are free to dismiss this whole thread because of this).

If this little breaking change is introduced in D, I am then forced to write foo like this:

void foo2(out int x) { x = 0; }

Is this a price small enough to pay for that increase in strictness?

Bye,
bearophile

Reply via email to