Classes or stucts :: Newbie

bearophile bearophileHUGS at lycos.com
Mon Dec 20 03:19:48 PST 2010


Jonathan M Davis:

> So, putting classes on the stack kind of negates the whole point of having
> both structs and classes in the first place.

Where you put the instance is mostly a matter of implementation. This is why a smart JavaVM is able to perform escape analysis and choose where to allocate the class instance.

Keep in mind that if you allocate a class on the stack or in-place inside another class, you don't turn it into a value, because beside the class instance you reserve space for its reference too (this reference may even be immutable, if you want).


> scoped classes are definitely not in SafeD.

Well implemented scoped classes are safe enough (compared to the other things). The compiler may perform escape analysis of all the aliases of a scoped object and statically raise an error if a reference escapes. This isn't 100% safe in a language that has all kind of casts and low-level features, but it's often safe enough, compared to other things. And those casts and low level features that can fool the escape analysis can be disabled statically (with something like @safe), this makes scoped classes 100% safe, probably safer than heap allocations.


>The whole point of "safe" when talking about safe in D is memory saftey.

I know, but some people (including me) think that "safe D" is a misleading name because it just means "memory safe D".


>If the compiler can determine that a particular class object can be put on the stack and optimize it that way. Fine, but it's pretty rare that it can do that - essentially only in cases where you don't pass it to _anything_ except for pure functions (including calls to member functions).

I don't agree that it's rare. If a function that allocates an object calls a function (or member function) that's present in the same compilation unit (this more or less means same module), then the compiler is able to continue the escape analysis and determine if the called function escapes the reference. If this doesn't happen, then the class instance is free to be scoped. This situation is common enough.


>And if the compiler can do that, then it there's no need for the programmer to use scope explicitly.<

I don't agree. An annotation like "@scope" is a contract between the programmer and the compiler. It means that if the compiler sees a reference escape, then it stops the compilation.


>And no, a compiler _can't_ do pure optimizations on its own, generally-speaking, because that would require looking not only at the body of the function that's being called but at the function bodies of any functions that it calls. D is not designed in a way that the compiler even necessarily has _access_ to a function's body when compiling, and you can't generally look at a function's body when doing optimizations when calling that function. So, _some_ pure optimizations could be done, but most couldn't. This is not the case with scoped classes, because purity already gives you the information that you need.<

Quite often a function calls another function in thee same compilation unit, in this case the analysis is possible. So you limit the optimizations to this common but limited case.

And LDC compiler and in future GDC too, have link-time optimization, this means the compiler packs or sees the program code code in a single compilation unit. In this case it's able to perform a more complete analysis (including de-virtualization of some virtual functions).


>Safety by convention means that the language and the compiler do not enforce it in any way.<

This is not fully true. If the syntax of the unsafe thing is ugly and long, the programmer is discouraged to use it. This makes the unsafe thing more visible for the eyes of the programmer. Statistically this may reduce bug count.


>There's nothing contradictory about Walter's stance. He's for having safety built into the language as much as reasonably possible and against having it thrust upon the programmer to program in a particular way to avoid unsafe stuff.<

I think you have missed part of the context of my comments for Nick Voronin, he was trying to say something here:

>Yet we won't have library solution for pointers instead of language support (hopefully)? :) I think it all goes against "being practical" as an objective of the language. Safety is important but you don't achieve safety by means of making unsafe thing unconvenient and inefficient. If there is emplace() then there is no reason not to have scope storage class. At least looking from user's POV. I don't know how hard it is on the compiler.<
>In _general_ case there is no safety in D. With all low-level capabilities one can always defeat compiler. Removing intermediate-level safer (yet unsafe) capabilities arguabily gains nothing but frustration. I'm all for encouraging good practices, but this is different.<

In D the convention is to not use certain low-level means to do something (and @safe statically forbids them, so it's not just a convention, I agree with you). But I am programming in D for some years and I have seen that some times (for performance or for other causes) you need to use the unsafe low-level features. In this case D leaves you on your own. You don't have something intermediate between the safe high level features and the unsafe C features. Nick and I feel the lack of this intermediate level of safety.

Then I have explained to Nick about the failure of Cyclone. It shows that implementing that intermediate level is hard, and it may lead to a not so good language. This is probably why Walter has chosen to avoid doing it. Despite the failure of Cyclone I am not sure Walter is right, and there may be a way to implement this intermediate level. I think the ATS language shows ways to do it, but it's a very hard to use language, "fifteen" times harder than D. So it's an open problem still.

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list