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