DIP 1028---Make @safe the Default---Community Review Round 1
Guillaume Piolat
first.last at gmail.com
Fri Jan 3 23:46:00 UTC 2020
On Friday, 3 January 2020 at 22:47:05 UTC, H. S. Teoh wrote:
> On Fri, Jan 03, 2020 at 10:23:41PM +0000, Guillaume Piolat via
> Digitalmars-d wrote:
>> On Friday, 3 January 2020 at 22:13:28 UTC, Steven
>> Schveighoffer wrote:
>> >
>> > I'd probably have to adjust a few things, and then it will
>> > build. The benefit is huge, because then someone doesn't
>> > have to choose between memory safety and iopipe speed. If
>> > the compiler complained about this when I was developing it,
>> > I'd fix the problems as they happened.
>> >
>>
>> Can anyone produce ONE example of a memory corruption code
>> they write that was found with use of marking something @safe?
>
> Ran into this a long time ago:
>
> struct ResourceA { /* ... */ }
> struct ResourceB { /* ... */ }
> // ...
>
> ResourceA getResourceA() @safe { return ResourceA(); }
> ResourceB getResourceB() @safe { return ResourceB(); }
> void freeResourceA(ResourceA*) @safe { /* ... */ }
> void freeResourceB(ResourceB*) @safe { /* ... */ }
>
> struct Container {
> ResourceA resA;
> ResourceB resB;
> // ...
>
> void delegate()[] dtors;
>
> this(int blah) /*@safe*/ {
> resA = getResourceA();
> dtors ~= { freeResourceA(&resA); };
>
> resB = getResourceB();
> dtors ~= { freeResourceA(&resA); };
>
> // ...
> }
> ~this() {
> // Cleanup resources
> foreach (dtor; dtors)
> dtor();
> }
> }
>
> The idea is that each allocated resource must be cleaned up
> when the container goes out of scope. To prevent cleanup code
> from going out of sync with allocation code, it's appended to a
> list of dtors immediately after allocation (sorta like a manual
> version of scope(exit) that works over an object's lifetime).
>
(I catched your bug while reading (&resA is dupe), but would make
similar bugs of course)
Just a note that people have sent me 3 such bugs they had and
that @safe indeed catch (sometimes in association with -dip1000)
------- sample 2 ---------
import std.stdio;
void main()
{
int[3] q;
oh(cast(int[4]*)(cast(void*)q));
}
void oh(int[4]* ar)
{
writeln(*ar);
}
------- sample 3 ----------
import std;
struct User
{
string username;
ubyte[] password;
}
ubyte[20] hashPassword(const(char)[] password) {
import std.digest.sha;
return sha1Of(password);
}
User admin;
void registerAdmin() {
auto hash = hashPassword("hello");
admin.username = "bob";
admin.password = hash;
}
void printAdmin() {
writeln(admin);
}
void main() {
registerAdmin();
printAdmin();
}
So we can get an idea of the kind of things it will catch.
More information about the Digitalmars-d
mailing list