www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Safe mode in D?

reply "DDD" <dcb854d0bfb1 f98b7c56a69c.anonbox.net> writes:
Hi I heard that you can pass a command line argument to make D 
safe. Like 0 chance of memory corruption and such. I tried 
looking here http://dlang.org/dmd-linux.html but I couldn't 
figure it out. If it matters I'm on windows using the latest 
until a new version came out ~3weeks ago
Oct 17 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 17 October 2013 at 22:56:04 UTC, DDD wrote:
 Hi I heard that you can pass a command line argument to make D 
 safe.
I don't think the command line argument is available anymore, instead it uses a function level annotation safe So, on the function you want, you put it down and then that function can only do memory safe operations and only call other safe, or manually verified trusted functions. To get it site wide, you can put it on main: safe void main() { // memory safe function } Note that not all standard library functions are properly marked safe, so not all stdlib functions will be available. Notably, writeln() in std.stdio is not marked safe... you can work around it by making a trusted writeln as described here http://stackoverflow.com/questions/19413340/escaping-safety-with-debug-statements
Oct 17 2013
parent reply "DDD" <dcb854d0bfb1 f98b7c56a69c.anonbox.net> writes:
On Thursday, 17 October 2013 at 23:03:52 UTC, Adam D. Ruppe wrote:
 On Thursday, 17 October 2013 at 22:56:04 UTC, DDD wrote:
 Hi I heard that you can pass a command line argument to make D 
 safe.
I don't think the command line argument is available anymore, instead it uses a function level annotation safe So, on the function you want, you put it down and then that function can only do memory safe operations and only call other safe, or manually verified trusted functions. To get it site wide, you can put it on main: safe void main() { // memory safe function } Note that not all standard library functions are properly marked safe, so not all stdlib functions will be available. Notably, writeln() in std.stdio is not marked safe... you can work around it by making a trusted writeln as described here http://stackoverflow.com/questions/19413340/escaping-safety-with-debug-statements
Is there a way to make everything safe by default and give me a compile error if it isn't?
Oct 17 2013
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 17 October 2013 at 23:08:12 UTC, DDD wrote:
 Is there a way to make everything safe by default and give me a 
 compile error if it isn't?
Not exactly. The closest you can get is putting safe on main, because then everything you call in the whole program would be forced to be safe too (because safe main won't be allowed to call unsafe ( system) functions, all the way down the chain, this is caught at compile time btw), or you can put safe: at the top of your file, then it will apply to everything beneath it in the whole module.
Oct 17 2013
prev sibling next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/17/2013 03:56 PM, DDD wrote:
 Hi I heard that you can pass a command line argument to make D safe.
 Like 0 chance of memory corruption and such. I tried looking here
 http://dlang.org/dmd-linux.html but I couldn't figure it out. If it
 matters I'm on windows using the latest until a new version came out
 ~3weeks ago
An example to complement Adam D. Ruppe's answer: /* system is the default */ system void can_do_anything() { int a; int * p = &a; } /* Must be trusted to be able to call function that are safe but not marked * as such. */ trusted void bridge_between_safe_and_actually_safe() { safe_but_not_marked_as_such(); } safe void safeD_function() { int a; // CANNOT BE COMPILED: // int * p = &a; // Can call trusted from safe bridge_between_safe_and_actually_safe(); } void safe_but_not_marked_as_such() {} void main() { can_do_anything(); bridge_between_safe_and_actually_safe(); safeD_function(); } Ali P.S. There is also the D.learn newsgroup. ;)
Oct 17 2013
parent reply "DDD" <dcb854d0bfb1 f98b7c56a69c.anonbox.net> writes:
On Thursday, 17 October 2013 at 23:08:13 UTC, Ali Çehreli wrote:
 On 10/17/2013 03:56 PM, DDD wrote:
 Hi I heard that you can pass a command line argument to make D 
 safe.
 Like 0 chance of memory corruption and such. I tried looking 
 here
 http://dlang.org/dmd-linux.html but I couldn't figure it out. 
 If it
 matters I'm on windows using the latest until a new version 
 came out
 ~3weeks ago
An example to complement Adam D. Ruppe's answer: /* system is the default */ system void can_do_anything() { int a; int * p = &a; } /* Must be trusted to be able to call function that are safe but not marked * as such. */ trusted void bridge_between_safe_and_actually_safe() { safe_but_not_marked_as_such(); } safe void safeD_function() { int a; // CANNOT BE COMPILED: // int * p = &a; // Can call trusted from safe bridge_between_safe_and_actually_safe(); } void safe_but_not_marked_as_such() {} void main() { can_do_anything(); bridge_between_safe_and_actually_safe(); safeD_function(); } Ali P.S. There is also the D.learn newsgroup. ;)
I tried this code and the compiler allowed it (runtime I get object.Error: Access Violation). What am I doing wrong? Thanks I didn't notice safe import std.stdio; class A { int x = 1; } safe void main() { A a; a.x=9; }
Oct 17 2013
next sibling parent reply "Meta" <jared771 gmail.com> writes:
On Thursday, 17 October 2013 at 23:18:21 UTC, DDD wrote:
 I tried this code and the compiler allowed it (runtime I get 
 object.Error: Access Violation). What am I doing wrong?

 Thanks I didn't notice

  safe
 import std.stdio;
 class A {
 	int x  = 1;
 }
  safe void main() {
 	A a;
 	a.x=9;
 }
This is more or less a different thing. SafeD doesn't guarantee that your class references will not be null. Trying to call a method on a null reference is perfectly valid in SafeD. There's a pull request sitting in GitHub for a NotNull type that should be reasonable good for ensuring that your references are not null, but it hasn't been pulled yet.
Oct 17 2013
next sibling parent "Meta" <jared771 gmail.com> writes:
An addendum: this is what SafeD guarantees.

http://dlang.org/safed.html
Oct 17 2013
prev sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Thursday, 17 October 2013 at 23:25:52 UTC, Meta wrote:
 On Thursday, 17 October 2013 at 23:18:21 UTC, DDD wrote:
 I tried this code and the compiler allowed it (runtime I get 
 object.Error: Access Violation). What am I doing wrong?

 Thanks I didn't notice

  safe
 import std.stdio;
 class A {
 	int x  = 1;
 }
  safe void main() {
 	A a;
 	a.x=9;
 }
This is more or less a different thing. SafeD doesn't guarantee that your class references will not be null. Trying to call a method on a null reference is perfectly valid in SafeD. There's a pull request sitting in GitHub for a NotNull type that should be reasonable good for ensuring that your references are not null, but it hasn't been pulled yet.
Actually on linux this will segfault so in general this is not safe across all platforms.
Oct 17 2013
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 18 October 2013 at 06:26:51 UTC, Maxim Fomin wrote:
 On Thursday, 17 October 2013 at 23:25:52 UTC, Meta wrote:
 On Thursday, 17 October 2013 at 23:18:21 UTC, DDD wrote:
 I tried this code and the compiler allowed it (runtime I get 
 object.Error: Access Violation). What am I doing wrong?

 Thanks I didn't notice

  safe
 import std.stdio;
 class A {
 	int x  = 1;
 }
  safe void main() {
 	A a;
 	a.x=9;
 }
This is more or less a different thing. SafeD doesn't guarantee that your class references will not be null. Trying to call a method on a null reference is perfectly valid in SafeD. There's a pull request sitting in GitHub for a NotNull type that should be reasonable good for ensuring that your references are not null, but it hasn't been pulled yet.
Actually on linux this will segfault so in general this is not safe across all platforms.
It's still memory safe in the sense that it's guaranteed to not stomp on anything -> no silent corruption. I don't really think the distinction between an Error or a segfault is the dividing line between safe and not safe. Both are supposed to be (under 99.9% of circumstances) unrecoverable errors.
Oct 18 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 18 October 2013 at 09:10:30 UTC, John Colvin wrote:
 On Friday, 18 October 2013 at 06:26:51 UTC, Maxim Fomin wrote:
 On Thursday, 17 October 2013 at 23:25:52 UTC, Meta wrote:
 On Thursday, 17 October 2013 at 23:18:21 UTC, DDD wrote:
 I tried this code and the compiler allowed it (runtime I get 
 object.Error: Access Violation). What am I doing wrong?

 Thanks I didn't notice

  safe
 import std.stdio;
 class A {
 	int x  = 1;
 }
  safe void main() {
 	A a;
 	a.x=9;
 }
This is more or less a different thing. SafeD doesn't guarantee that your class references will not be null. Trying to call a method on a null reference is perfectly valid in SafeD. There's a pull request sitting in GitHub for a NotNull type that should be reasonable good for ensuring that your references are not null, but it hasn't been pulled yet.
Actually on linux this will segfault so in general this is not safe across all platforms.
It's still memory safe in the sense that it's guaranteed to not stomp on anything -> no silent corruption.
Well, in some sence yes. The problem with dereferencing nulls is that behavior is different in linux and windows (i.e. non portable), but you can enable treating nulls as exception in linux if you use etc.linux.memoryerrors.
 I don't really think the distinction between an Error or a 
 segfault is the dividing line between safe and not safe. Both 
 are supposed to be (under 99.9% of circumstances) unrecoverable 
 errors.
Some errors are propagated as exceptions, some errors are handled like abort, so situation depends on type of the error. Users are not supposed to catch errors, but they still can, which makes situation is compilcated in general. However, dereferencing null is tiny problem comparing to other issues in D's safity.
Oct 18 2013
parent "Wyatt" <wyatt.epp gmail.com> writes:
On Friday, 18 October 2013 at 10:03:03 UTC, Maxim Fomin wrote:
 portable), but you can enable treating nulls as exception in 
 linux if you use etc.linux.memoryerrors.
Oh. This exists. Don't suppose there were any plans to document it? -Wyatt
Oct 18 2013
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Thursday, 17 October 2013 at 23:18:21 UTC, DDD wrote:
 I tried this code and the compiler allowed it (runtime I get 
 object.Error: Access Violation). What am I doing wrong?
D doesn't consider null pointer deference to be unsafe, since its behavior is predictable (the hardware will catch it and kill the program). This btw is arguably wrong, since dereferencing a large null object can potentially overwrite other stuff, but it is how it is right now. safe prohibits casting ints to pointers, doing pointer arithmetic, and other similar things that can create hard to find bugs and other undefined behavior.
Oct 17 2013
prev sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Thursday, 17 October 2013 at 23:18:21 UTC, DDD wrote:
 I tried this code and the compiler allowed it (runtime I get 
 object.Error: Access Violation). What am I doing wrong?

 Thanks I didn't notice

  safe
 import std.stdio;
 class A {
 	int x  = 1;
 }
  safe void main() {
 	A a;
 	a.x=9;
 }
Yes, compiler allows it. But this is basic case. Here is D' Bugs Hall Of Fame (collection of memory errors, type system breakages and other cases to shoot your foot provided by bugzilla issues, me and other people) : // --- Case 1. Breaking all of type system through delegates --- // extern(C) system int printf(const char*, ...); auto frame1() pure nothrow safe { immutable void delegate() pure nothrow safe x; auto tmp = { return x; } ; return tmp; } auto frame2(T)(T t) pure nothrow safe { void delegate() system x; x.funcptr = t; return { return x; } ; } void bar() { printf("pure nothrow safe loophole\n"); } system void main() safe pure nothrow { //bar(); Error: ... auto fm1 = frame1(); auto fm2 = frame2(&bar); fm1.ptr = fm2.ptr; fm1()(); fm2 = frame2({ printf("pure nothrow safe loophole\n"); }); fm1.ptr = fm2.ptr; fm1()(); } // ---- Case 2. Breaking immutability ---- // import std.stdio; class A { int[] c = [3,3]; } void main() { int[] a = [2,2]; int[] b = [2,2]; a[0] = 33; assert(b[0] == 2); // success A ca = new A; // assume that one of them is immutable A cb = new A; ca.c[0] = 44; assert(cb.c[0] == 3); // failure: value is 44 } // ---- Case 3. Breaking type system via delegates ---- // class A { int i; void foo() { ++i; } } void main() { immutable a = new immutable A; //a.foo(); (&a.foo)(); } // --- Case 4. Mutating immutable -- // immutable int i; void f(ref int n = i) { ++n; // hello to those who thinks immutable never changes } import std.stdio; void main() { f(); writeln(i); } // -- Case 5. Memory corruption via lazy --- // extern(C) int printf(const char*,...) safe; alias int T; auto foo(lazy T i) safe { return { return i; } ; } auto bar() safe { T i = 4; return foo(i); } void baz() safe { double[2] i = 3.14; } void main() safe { auto x = bar(); baz(); printf("%d\n", x()); }
Oct 18 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 18 October 2013 at 07:04:39 UTC, Maxim Fomin wrote:
 On Thursday, 17 October 2013 at 23:18:21 UTC, DDD wrote:
 I tried this code and the compiler allowed it (runtime I get 
 object.Error: Access Violation). What am I doing wrong?

 Thanks I didn't notice

  safe
 import std.stdio;
 class A {
 	int x  = 1;
 }
  safe void main() {
 	A a;
 	a.x=9;
 }
Yes, compiler allows it. But this is basic case. Here is D' Bugs Hall Of Fame (collection of memory errors, type system breakages and other cases to shoot your foot provided by bugzilla issues, me and other people) :
Moar :) // ---- Case 6. UDA bugs - purity loophole ---- // // discovered by Timon Gehr import std.stdio; int x; (write(x++),writeln()) void foo(){} safe pure void main(){ __traits(getAttributes, foo); __traits(getAttributes, foo)[0]; __traits(getAttributes, foo)[0]; //write(x++), writeln(); // Error: pure function cannot ... } // ---- Case 7. Writing to typeinfo in purity code ---- // import core.stdc.string, std.stdio; pure void rtSetDefaultHeapInitializer(T)(T value) if (is(T == class)) { byte[] init_mem = new byte[T.classinfo.init.length]; memcpy(init_mem.ptr, cast(byte*)value, T.classinfo.init.length); T.classinfo.init = init_mem; } class A { int a; } int foo() pure { A a = new A; a.a++; rtSetDefaultHeapInitializer(a); return a.a; } void main() { writeln(foo, foo, foo); } // ---- Case 8. Escaping references and memory bugs ---- // import std.stdio; alias long[100] T; T delegate() dg; //ref T foo(ref T i) safe void foo(ref T i) safe { dg = { return i; } ; //return i; } //ref T bar() void bar() safe { T i = 1; //return foo(i); foo(i); } void rewrite_stack() safe { T tmp = -1; } void main() { //T i = bar(); bar(); rewrite_stack(); writeln(dg()); } This is not so obvious as previous. // ---- Case 9. Escaping static arrays. ---- // import std.stdio; class A { int[] data; ~this() { writeln(data); } } void foo(int[] a) safe { A x = new A; x.data = a; } void main() safe { int[4] y; foo(y); } // ---- Case 10. Mutating immutable ---- // import std.stdio; immutable int i; immutable int *ptr; static this() { ++i, ptr = &i; } void main() { foreach (i; 0 .. 10) { _staticCtor1(); writeln(i); } } (Basically problem here is that nether dmd nor linker cares about symbol protection) // --- Case 11. Writing to global though pure functions ---- // int a; pure foo(ref int a = a) { ++a; } void main() pure { foo(); } // ---- Case 12. Breaking immutable via pure ---- // import std.stdio; import core.memory; class A { int *ptr; ~this() { (*ptr)++; } } pure foo() { A a = new A; int* ptr = new int; a.ptr = ptr; a = null; return ptr; } void main() { immutable int* ptr = foo(); writeln(*ptr); // 0 GC.collect(); writeln(*ptr); // 1 } The latest bug is nice, because after 2.063 Kenji has fixed the language, improving consistency of calling immutable/const qualified constructors, but allowed to cast return value of pure function to immutable because there was belief that inside purity function value cannot escape. Such ideom was advertised several times in this newsgroups. It appears that idea is not reliable. Probably there are other cases. tl;dr do not take into account D' type system and safety seriously.
Oct 18 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10/18/2013 09:30 AM, Maxim Fomin wrote:
 ...
Nice collection.
 // ---- Case 12. Breaking immutable via pure ---- //

 import std.stdio;
 import core.memory;

 class A
 {
     int *ptr;
     ~this()
     {
        (*ptr)++;
     }
 }

 pure foo()
 {
     A a = new A;
     int* ptr = new int;
     a.ptr = ptr;
     a = null;
     return ptr;
 }

 void main()
 {
     immutable int* ptr = foo();
     writeln(*ptr); // 0
     GC.collect();
     writeln(*ptr); // 1
 }

 The latest bug is nice, because after 2.063 Kenji has fixed the
 language, improving consistency of calling immutable/const qualified
 constructors, but allowed to cast return value of pure function to
 immutable because there was belief that inside purity function value
 cannot escape. Such ideom was advertised several times in this
 newsgroups. It appears that idea is not reliable.
It's no less of a design issue, but the main problem is actually that class destructors are unsafe in general. import core.memory; class A{ int *ptr; this(immutable int* ptr)immutable{ this.ptr = ptr; } ~this(){ (*ptr)++; } } immutable y = 2; void main(){ auto x = new immutable(A)(&y); GC.collect(); assert(*&y==y); // fails } Of course, safe implicit conversions to immutable do not simplify any attempt to solve this, but the feature is not essential to the problem.
 Probably there are other cases.

 tl;dr do not take into account D' type system and safety seriously.
Your other examples are just DMD bugs afaics. (With the possible exception of delegate context pointer memory safety, but that is a simple fix.)
Oct 18 2013
prev sibling next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Thursday, 17 October 2013 at 22:56:04 UTC, DDD wrote:
 Hi I heard that you can pass a command line argument to make D 
 safe. Like 0 chance of memory corruption and such. I tried 
 looking here http://dlang.org/dmd-linux.html but I couldn't 
 figure it out. If it matters I'm on windows using the latest 
 until a new version came out ~3weeks ago
Safe code in D is defective feature and claims that D's code can be memory safe is the biggest misconception! First of all, safe is broken, which means there are many cases when code should be rejected, but actually isn't, secondly it is misdesigned. Root of the issue is that in D static type system and memory safity are separated from each other. Key idea is that having information about static type of object is not sufficient to know whether using it is memory safe or not. safe foo(int[] arr) {} void main safe() { int [3] x; // auto dg = { return x; } ; foo(x[]); } This a nice case to show safe problems. First of all, passing static array to dynamic is of relative safety: if slice doesn't escape, this is fine, if is does, this can be still fine if it later for example is appended (or any operation is performed which does not access any elements). Otherwise it is a memory bug. In a presence of separate compilation this is impossible to know. In such cases memory safety is at best undefined. Other issue here is that if delegate declaration is uncommented, then code is always memory safe because array will be allocated on heap. However, by safe definition code will be still rejected, because safe is defined in notion of static type rather than memory type. Last issue here is that implementation is buggy and does not reject the code in accordance with its buggy spec. And at last, there are cases in the language which are not covered by safe spec, but which still produce memory errors. So, what actually D has, is a feature, which does not really prevents memory errors, but bans some language features and criteria for banning features is wrong: some legal cases are banned, some cases which should be blocked, are not. If you are really interested in safety you can put our attention to languages like C#. D doesn't provide such facilities.
Oct 17 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/17/13 11:53 PM, Maxim Fomin wrote:
 Root of the issue is that in D static type system and memory safity are
 separated from each other. Key idea is that having information about
 static type of object is not sufficient to know whether using it is
 memory safe or not.
This is a common approach in many languages (actually all that I know about). Clearly stuff on the stack can be attached an invisible attribute "it's on the stack!" but that doesn't go well with separate compilation. Thanks for collecting together the situations where safety is broken. It's a bummer your posts are perpetually gloomy, but there's hope we may be able to do something about that. I'd like to make improving safe the focus of 2.065, by fixing the implementation bugs and by looking at the more complicated cases, too.
 So, what actually D has, is a feature, which does not really prevents
 memory errors, but bans some language features and criteria for banning
 features is wrong: some legal cases are banned, some cases which should
 be blocked, are not. If you are really interested in safety you can put
 our attention to languages like C#. D doesn't provide such facilities.
It's a given that safety will disallow constructs that are safe upon inspection but the type system is unable to prove correct. This is the case for all languages, C# included. Andrei
Oct 18 2013
next sibling parent "Dicebot" <public dicebot.lv> writes:
On Friday, 18 October 2013 at 15:39:35 UTC, Andrei Alexandrescu 
wrote:
 This is a common approach in many languages (actually all that 
 I know about). Clearly stuff on the stack can be attached an 
 invisible attribute "it's on the stack!" but that doesn't go 
 well with separate compilation.
As we don't provide ABI stability guarantees yet, it is not too late to make all important type system properties part of symbol mangling.
Oct 18 2013
prev sibling parent reply Paulo Pinto <pjmlp progtools.org> writes:
Am 18.10.2013 17:40, schrieb Andrei Alexandrescu:
 On 10/17/13 11:53 PM, Maxim Fomin wrote:
 ...
It's a given that safety will disallow constructs that are safe upon inspection but the type system is unable to prove correct. This is the case for all languages, C# included. Andrei
Wouldn't be easier, if D followed a model similar to C# and Modula-3 where the code is by default safe and system/trusted code is only allowed inside explicitly unsafe code blocks? Just an idea, maybe it wouldn't be much different from what it is now. -- Paulo
Oct 18 2013
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 18, 2013 at 06:34:07PM +0200, Paulo Pinto wrote:
 Am 18.10.2013 17:40, schrieb Andrei Alexandrescu:
On 10/17/13 11:53 PM, Maxim Fomin wrote:
...
It's a given that safety will disallow constructs that are safe upon inspection but the type system is unable to prove correct. This is the case for all languages, C# included. Andrei
Wouldn't be easier, if D followed a model similar to C# and Modula-3 where the code is by default safe and system/trusted code is only allowed inside explicitly unsafe code blocks? Just an idea, maybe it wouldn't be much different from what it is now.
[...] It would break existing code. But if we're gonna do it, I say we should go all the way: make safe, pure, and nothrow default, and require annotations only for system, impure, throwing. If we advertise D as "do the right thing by default, but allow the user to override it if necessary", then we should make all code safe, pure, and nothrow by default. (Well, at the very least safe and pure, I'm not as sure about making nothrow default. But it would be nice for those performance-conscious people who don't like the fact that throwing functions require extra stack frame setup, which thus impacts performance.) T -- One Word to write them all, One Access to find them, One Excel to count them all, And thus to Windows bind them. -- Mike Champion
Oct 18 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 18 October 2013 at 17:06:57 UTC, H. S. Teoh wrote:
 But if we're gonna do it, I say we should go all the way:
And make scope the default parameter thingy, and implement it. God I want some kind of escaping check thing so badly, it is supposed to work already! http://dlang.org/function.html scope: references in the parameter cannot be escaped (e.g. assigned to a global variable) But what's interesting here is that references to immutable are virtually value types; string, or immutable(int)[] *can* be escaped safely, whereas const(int)[] or int[] might not, they can be overwritten elsewhere (the case now) and can also be freed elsewhere (if you don't use the gc on them). An immutable reference would necessarily use the gc, since otherwise it isn't really immutable. So you can store immutable stuff in a global or anything and that's perfectly ok, so scope immutable == immutable. scope const is different though.
 I'm not as sure about making nothrow default.
i think throwing is really the default anyway just writing normal D. If we sampled 100 random D functions, I think we'd find most of them are safe in practice, even if not marked, and probably throw too. So that'd be the sane default.
Oct 18 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 18 October 2013 at 17:19:17 UTC, Adam D. Ruppe wrote:
 On Friday, 18 October 2013 at 17:06:57 UTC, H. S. Teoh wrote:
 But if we're gonna do it, I say we should go all the way:
And make scope the default parameter thingy, and implement it. God I want some kind of escaping check thing so badly, it is supposed to work already!
Yeah it is astonishing how many holes in type system implementing that single small thing can fix. I wish it never was in documentation, that way I would not have bothered me that much at least :)
Oct 18 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 18, 2013 at 07:25:03PM +0200, Dicebot wrote:
 On Friday, 18 October 2013 at 17:19:17 UTC, Adam D. Ruppe wrote:
On Friday, 18 October 2013 at 17:06:57 UTC, H. S. Teoh wrote:
But if we're gonna do it, I say we should go all the way:
And make scope the default parameter thingy, and implement it. God I want some kind of escaping check thing so badly, it is supposed to work already!
Yeah it is astonishing how many holes in type system implementing that single small thing can fix. I wish it never was in documentation, that way I would not have bothered me that much at least :)
So what's the hold up? Just the lack of manpower to actually implement it? I wish there were a time store I could buy more spare time from so that I could actually work on D stuff on top of all the other stuff I'm busy with... T -- Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
Oct 18 2013
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, October 18, 2013 10:31:55 H. S. Teoh wrote:
 On Fri, Oct 18, 2013 at 07:25:03PM +0200, Dicebot wrote:
 On Friday, 18 October 2013 at 17:19:17 UTC, Adam D. Ruppe wrote:
On Friday, 18 October 2013 at 17:06:57 UTC, H. S. Teoh wrote:
But if we're gonna do it, I say we should go all the way:
And make scope the default parameter thingy, and implement it. God I want some kind of escaping check thing so badly, it is supposed to work already!
Yeah it is astonishing how many holes in type system implementing that single small thing can fix. I wish it never was in documentation, that way I would not have bothered me that much at least :)
So what's the hold up? Just the lack of manpower to actually implement it?
The facts that escape analysis tends to be difficult and that Walter generally refuses to do anything in the compiler which involves flow analysis would tend to make scope very difficult to implement properly. I don't know that Walter has any plans with regards to scope at this point or not. At the moment, it seems to be relegated to delegates only, and even there, it's not fully implemented. AFAIK, no plans beyond that for scope have ever been announced. It's just that the way that it's defined in the spec implies that it would work with any reference type. - Jonathan M Davis
Oct 18 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 18, 2013 at 01:38:12PM -0400, Jonathan M Davis wrote:
 On Friday, October 18, 2013 10:31:55 H. S. Teoh wrote:
 On Fri, Oct 18, 2013 at 07:25:03PM +0200, Dicebot wrote:
 On Friday, 18 October 2013 at 17:19:17 UTC, Adam D. Ruppe wrote:
On Friday, 18 October 2013 at 17:06:57 UTC, H. S. Teoh wrote:
But if we're gonna do it, I say we should go all the way:
And make scope the default parameter thingy, and implement it. God I want some kind of escaping check thing so badly, it is supposed to work already!
Yeah it is astonishing how many holes in type system implementing that single small thing can fix. I wish it never was in documentation, that way I would not have bothered me that much at least :)
So what's the hold up? Just the lack of manpower to actually implement it?
The facts that escape analysis tends to be difficult and that Walter generally refuses to do anything in the compiler which involves flow analysis would tend to make scope very difficult to implement properly.
What's the reason for refusing to implement flow analysis? Maybe I'm missing something obvious, but for the purposes of escape analysis, isn't it enough to just have a simple one-pass flow analysis? Do we really need full-scale flow analysis in order to do escape analysis?
 I don't know that Walter has any plans with regards to scope at this
 point or not. At the moment, it seems to be relegated to delegates
 only, and even there, it's not fully implemented.  AFAIK, no plans
 beyond that for scope have ever been announced. It's just that the way
 that it's defined in the spec implies that it would work with any
 reference type.
[...] Well, then we should either change the spec, or make concrete plans on how to implement it. The current state of limbo that scope is only generates bad rep for D while offering nothing in return. T -- Right now I'm having amnesia and deja vu at the same time. I think I've forgotten this before.
Oct 18 2013
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Oct 18, 2013 at 07:19:16PM +0200, Adam D. Ruppe wrote:
 On Friday, 18 October 2013 at 17:06:57 UTC, H. S. Teoh wrote:
But if we're gonna do it, I say we should go all the way:
And make scope the default parameter thingy, and implement it. God I want some kind of escaping check thing so badly, it is supposed to work already!
+1. I'm waiting for scope to be implemented too. Walter: Just out of curiosity, what exactly is holding up the implementation of scope? AFAICT, a relatively simple one-pass flow analysis would do the job; am I missing something obvious?
 http://dlang.org/function.html
 scope: references in the parameter cannot be escaped (e.g. assigned to
 a global variable)
 
 
 But what's interesting here is that references to immutable are
 virtually value types; string, or immutable(int)[] *can* be escaped
 safely, whereas const(int)[] or int[] might not, they can be
 overwritten elsewhere (the case now) and can also be freed elsewhere
 (if you don't use the gc on them). An immutable reference would
 necessarily use the gc, since otherwise it isn't really immutable.
 
 So you can store immutable stuff in a global or anything and that's
 perfectly ok, so scope immutable == immutable. scope const is
 different though.
Interesting. Though I'm still unclear about the meaning of a scope delegate (its *intended* meaning, that is, not necessarily its current implementation).
I'm not as sure about making nothrow default.
i think throwing is really the default anyway just writing normal D. If we sampled 100 random D functions, I think we'd find most of them are safe in practice, even if not marked, and probably throw too. So that'd be the sane default.
True, most "normal" D code would allow throwing exceptions, since that's a core language feature, so nothrow shouldn't be default. But pure and safe *should* be default IMO. T -- English is useful because it is a mess. Since English is a mess, it maps well onto the problem space, which is also a mess, which we call reality. Similarly, Perl was designed to be a mess, though in the nicests of all possible ways. -- Larry Wall
Oct 18 2013
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10/18/2013 07:30 PM, H. S. Teoh wrote:
  Walter: Just out of curiosity, what exactly is holding up the
 implementation of scope?
 ...
The missing design of scope, I guess.
Oct 18 2013
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, October 18, 2013 10:05:39 H. S. Teoh wrote:
 It would break existing code.
 
 But if we're gonna do it, I say we should go all the way: make  safe,
 pure, and nothrow default, and require annotations only for  system,
 impure, throwing. If we advertise D as "do the right thing by default,
 but allow the user to override it if necessary", then we should make all
 code  safe, pure, and nothrow by default. (Well, at the very least  safe
 and pure, I'm not as sure about making nothrow default. But it would be
 nice for those performance-conscious people who don't like the fact that
 throwing functions require extra stack frame setup, which thus impacts
 performance.)
Yeah, if we could go back, it would be great to do something like that, but I think that it's pretty clear that it would be too much of a breaking change at this point. - Jonathan M Davis
Oct 18 2013
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, October 18, 2013 10:41:38 H. S. Teoh wrote:
 On Fri, Oct 18, 2013 at 01:38:12PM -0400, Jonathan M Davis wrote:
 What's the reason for refusing to implement flow analysis? Maybe I'm
 missing something obvious, but for the purposes of escape analysis,
 isn't it enough to just have a simple one-pass flow analysis? Do we
 really need full-scale flow analysis in order to do escape analysis?
I think that it's mainly a question of complexity. Walter doesn't want to add that kind of complexity to the compiler - especially when that means making the language requires it, because that makes writing tools for the language harder. Given his stance on flow analysis, I'm actually kind of surprised that scope ever made it into the language at all.
 I don't know that Walter has any plans with regards to scope at this
 point or not. At the moment, it seems to be relegated to delegates
 only, and even there, it's not fully implemented. AFAIK, no plans
 beyond that for scope have ever been announced. It's just that the way
 that it's defined in the spec implies that it would work with any
 reference type.
[...] Well, then we should either change the spec, or make concrete plans on how to implement it. The current state of limbo that scope is only generates bad rep for D while offering nothing in return.
scope's future definitely needs to be sorted out. I find the fact that compiles and is simply ignored when it's not valid particularly bad. And the fact that in is an alias for const scope is probably going to cause a lot of problems if/when scope is fully implemented because of how many people use in simply because they like how it seems like the opposite of out, but they don't take into account that the code in question won't work with scope. - Jonathan M Davis
Oct 18 2013
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/18/13 10:53 AM, Jonathan M Davis wrote:
 On Friday, October 18, 2013 10:41:38 H. S. Teoh wrote:
 On Fri, Oct 18, 2013 at 01:38:12PM -0400, Jonathan M Davis wrote:
 What's the reason for refusing to implement flow analysis? Maybe I'm
 missing something obvious, but for the purposes of escape analysis,
 isn't it enough to just have a simple one-pass flow analysis? Do we
 really need full-scale flow analysis in order to do escape analysis?
I think that it's mainly a question of complexity. Walter doesn't want to add that kind of complexity to the compiler - especially when that means making the language requires it, because that makes writing tools for the language harder. Given his stance on flow analysis, I'm actually kind of surprised that scope ever made it into the language at all.
I think one good compromise is to stick with the exact amount of flow control we currently have in constructors (which is primitive but quite adequate), and use that creatively. It's already implemented and works, so the implementation costs of applying it to other cases should be low. Andrei
Oct 18 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 18 October 2013 at 18:59:46 UTC, Andrei Alexandrescu 
wrote:
 I think one good compromise is to stick with the exact amount 
 of flow control we currently have in constructors (which is 
 primitive but quite adequate), and use that creatively. It's 
 already implemented and works, so the implementation costs of 
 applying it to other cases should be low.

 Andrei
Do you mean preventing calling constructor (from another constructor) within one control branch? May be this will be case #13. import std.stdio; extern(C) void _D4main1A6__ctorMFiZC4main1A(A a, int i); class A { this(int i) { writeln("reached"); } this() { int i = 1; //if (i) // this(i); // Error: one path skips constructor if (i) _D4main1A6__ctorMFiZC4main1A(this, i); if (i) auto dg = __traits(getOverloads, this, "__ctor")[0](i); } } void main() { new A; }
Oct 18 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Friday, 18 October 2013 at 19:28:35 UTC, Maxim Fomin wrote:
 On Friday, 18 October 2013 at 18:59:46 UTC, Andrei Alexandrescu 
 wrote:
 I think one good compromise is to stick with the exact amount 
 of flow control we currently have in constructors (which is 
 primitive but quite adequate), and use that creatively. It's 
 already implemented and works, so the implementation costs of 
 applying it to other cases should be low.

 Andrei
Do you mean preventing calling constructor (from another constructor) within one control branch? May be this will be case #13. import std.stdio; extern(C) void _D4main1A6__ctorMFiZC4main1A(A a, int i); class A { this(int i) { writeln("reached"); } this() { int i = 1; //if (i) // this(i); // Error: one path skips constructor if (i) _D4main1A6__ctorMFiZC4main1A(this, i); if (i) auto dg = __traits(getOverloads, this, "__ctor")[0](i); } } void main() { new A; }
Wanna talk about what can be done with reflection in "safe" C#?
Oct 18 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 18 October 2013 at 19:46:44 UTC, Max Samukha wrote:
 On Friday, 18 October 2013 at 19:28:35 UTC, Maxim Fomin wrote:
 On Friday, 18 October 2013 at 18:59:46 UTC, Andrei 
 Alexandrescu wrote:
 I think one good compromise is to stick with the exact amount 
 of flow control we currently have in constructors (which is 
 primitive but quite adequate), and use that creatively. It's 
 already implemented and works, so the implementation costs of 
 applying it to other cases should be low.

 Andrei
Do you mean preventing calling constructor (from another constructor) within one control branch? May be this will be case #13. import std.stdio; extern(C) void _D4main1A6__ctorMFiZC4main1A(A a, int i); class A { this(int i) { writeln("reached"); } this() { int i = 1; //if (i) // this(i); // Error: one path skips constructor if (i) _D4main1A6__ctorMFiZC4main1A(this, i); if (i) auto dg = __traits(getOverloads, this, "__ctor")[0](i); } } void main() { new A; }
Wanna talk about what can be done with reflection in "safe" C#?
You are free to present horrible bugs of "unsafe" C#, but I bet they are far, very far to DMD bugs/D design issues of "safe" D. (By the way, I don't see why the code above provoked you to C# talks).
Oct 18 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Friday, 18 October 2013 at 20:03:22 UTC, Maxim Fomin wrote:

 (By the way, I don't see why the code above provoked you to C#
 talks).
Because you: 1) Mentioned C# as a safer alternative to D. 2) Are using reflection to demonstrate D's unsafety. Try this: using System; using System.Reflection; namespace test { class A { public int x; public A() { x += 1; } } class App { public static void Main (string[] args) { var a = new A(); var ctor = a.GetType().GetConstructor(new Type[] {}); ctor.Invoke(a, new object[] {}); ctor.Invoke(a, new object[] {}); Console.Write(a.x); } } }
Oct 18 2013
next sibling parent reply "ProgrammingGhost" <dsioafiseghvfawklncfskzdcf sdifjsdiovgfdisjcisj.com> writes:
On Friday, 18 October 2013 at 22:29:45 UTC, Max Samukha wrote:
 On Friday, 18 October 2013 at 20:03:22 UTC, Maxim Fomin wrote:

 (By the way, I don't see why the code above provoked you to C#
 talks).
Because you: 1) Mentioned C# as a safer alternative to D. 2) Are using reflection to demonstrate D's unsafety. Try this: using System; using System.Reflection; namespace test { class A { public int x; public A() { x += 1; } } class App { public static void Main (string[] args) { var a = new A(); var ctor = a.GetType().GetConstructor(new Type[] {}); ctor.Invoke(a, new object[] {}); ctor.Invoke(a, new object[] {}); Console.Write(a.x); } } }
I'm not sure why this is entirely bad. It looks like you're asking it to call the constructor a few times. If it allocates memory the GC should clean it up. Whats 'wrong' with this code?
Oct 18 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Friday, 18 October 2013 at 23:03:42 UTC, ProgrammingGhost 
wrote:

 Whats 'wrong' with this code?
Nothing, that's the point. Just like with __traits(getOverloads, this, "__ctor")[0](i). In my world, safety features of a language are meant to help a fairly reasonable programmer avoid accidental mistakes. Misusing reflection or C interface is not an accidental mistake.
Oct 18 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 19 October 2013 at 06:54:32 UTC, Max Samukha wrote:
 On Friday, 18 October 2013 at 23:03:42 UTC, ProgrammingGhost 
 wrote:

 Whats 'wrong' with this code?
Nothing, that's the point. Just like with __traits(getOverloads, this, "__ctor")[0](i). In my world, safety features of a language are meant to help a fairly reasonable programmer avoid accidental mistakes. Misusing reflection or C interface is not an accidental mistake.
Actual definition of safity in D is "Safe functions are functions that are statically checked to exhibit no possibility of undefined behavior. Undefined behavior is often used as a vector for malicious attacks. " I provided many cases where this does not happen.
Oct 19 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 07:24:49 UTC, Maxim Fomin wrote:

 Actual definition of safity in D is "Safe functions are 
 functions that are statically checked to exhibit no possibility 
 of undefined behavior. Undefined behavior is often used as a 
 vector for malicious attacks. " I provided many cases where 
 this does not happen.
I know the definition. Aren't we discussing a different matter - your dissatisfaction with the fact that D's control flow analysis does not prevent indirect calls to the constructor?
Oct 19 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 19 October 2013 at 07:42:24 UTC, Max Samukha wrote:
 On Saturday, 19 October 2013 at 07:24:49 UTC, Maxim Fomin wrote:

 Actual definition of safity in D is "Safe functions are 
 functions that are statically checked to exhibit no 
 possibility of undefined behavior. Undefined behavior is often 
 used as a vector for malicious attacks. " I provided many 
 cases where this does not happen.
I know the definition. Aren't we discussing a different matter - your dissatisfaction with the fact that D's control flow analysis does not prevent indirect calls to the constructor?
No. Topic of the thread is Safe D. The point was made that D's safe mode is not safe at all. Constructor invocation is a spin-off of the topic. By the way, no dissatisfaction here, as I don't by D premises at all.
Oct 19 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 08:25:58 UTC, Maxim Fomin wrote:
 On Saturday, 19 October 2013 at 07:42:24 UTC, Max Samukha wrote:
 On Saturday, 19 October 2013 at 07:24:49 UTC, Maxim Fomin 
 wrote:

 Actual definition of safity in D is "Safe functions are 
 functions that are statically checked to exhibit no 
 possibility of undefined behavior. Undefined behavior is 
 often used as a vector for malicious attacks. " I provided 
 many cases where this does not happen.
I know the definition. Aren't we discussing a different matter - your dissatisfaction with the fact that D's control flow analysis does not prevent indirect calls to the constructor?
No. Topic of the thread is Safe D. The point was made that D's safe mode is not safe at all. Constructor invocation is a spin-off of the topic.
It's you who made that spin-off, trying to foist it in as yet another example of D's unsafety. I was replying to that.
 By the way, no dissatisfaction here, as I don't by D premises at
 all.
You sounded dissatisfied.
Oct 19 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 19 October 2013 at 08:40:08 UTC, Max Samukha wrote:
 On Saturday, 19 October 2013 at 08:25:58 UTC, Maxim Fomin wrote:
 On Saturday, 19 October 2013 at 07:42:24 UTC, Max Samukha 
 wrote:
 On Saturday, 19 October 2013 at 07:24:49 UTC, Maxim Fomin 
 wrote:

 Actual definition of safity in D is "Safe functions are 
 functions that are statically checked to exhibit no 
 possibility of undefined behavior. Undefined behavior is 
 often used as a vector for malicious attacks. " I provided 
 many cases where this does not happen.
I know the definition. Aren't we discussing a different matter - your dissatisfaction with the fact that D's control flow analysis does not prevent indirect calls to the constructor?
No. Topic of the thread is Safe D. The point was made that D's safe mode is not safe at all. Constructor invocation is a spin-off of the topic.
It's you who made that spin-off, trying to foist it in as yet another example of D's unsafety. I was replying to that.
It seems you missed the point - see second post in page 5. Actually aggregate name of collection was "(collection of memory errors, type system breakages and other cases to shoot your foot provided by bugzilla issues, me and other people)". It doesn't mean that each example shows memory error bug. Obviously this case doesn't show unsafity, it shows that the limitation imposed on the language is arbitrary and groundless.
 By the way, no dissatisfaction here, as I don't by D premises 
 at
 all.
You sounded dissatisfied.
No, I can't be, because I don't buy D promises at all. Man cannot be dissatisfied with something when he expects thing to be broken and it actually happens.
Oct 19 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 08:45:05 UTC, Maxim Fomin wrote:

 Actually aggregate name of collection was "(collection of memory
 errors, type  system breakages and other cases to shoot your 
 foot
 provided by bugzilla issues, me and other people)".
And we are back to square one - misusing extern(C) and reflection to call the constructor as you showed in #13 does not belong in that collection.
Oct 19 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 19 October 2013 at 09:26:53 UTC, Max Samukha wrote:
 On Saturday, 19 October 2013 at 08:45:05 UTC, Maxim Fomin wrote:

 Actually aggregate name of collection was "(collection of 
 memory
 errors, type  system breakages and other cases to shoot your 
 foot
 provided by bugzilla issues, me and other people)".
And we are back to square one - misusing extern(C) and reflection to call the constructor as you showed in #13 does not belong in that collection.
OK, you can remove extern(c) trick (however, it is not clear, why it shouldn't be counted as a type system hole) and you still have "reflection hole". I came up with the code in response to Andrei who said that constructor control flow is "primitive but quite adequate" and which "is already implemented and works". What "primitive but quite adequate" does mean is subjective, but it does not really prevent from what it is suppose to prevent. Of course in this case you do not corrupt memory or write to immutable (I am telling this for the third time). The point was made why would you have such constraint if it is easily avoidable? How much sense is in the constraint which does not provide real value (except probably as an exercise in implementing abstract programming theories from academia) nor is properly reinforced?
Oct 19 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 10:50:42 UTC, Maxim Fomin wrote:

 OK, you can remove extern(c) trick (however, it is not clear, 
 why it shouldn't be counted as a type system hole) and you 
 still have "reflection hole".

 I came up with the code in response to Andrei who said that 
 constructor control flow is "primitive but quite adequate" and 
 which "is already implemented and works". What "primitive but 
 quite adequate" does mean is subjective, but it does not really 
 prevent from what it is suppose to prevent. Of course in this 
 case you do not corrupt memory or write to immutable (I am 
 telling this for the third time). The point was made why would 
 you have such constraint if it is easily avoidable? How much 
 sense is in the constraint which does not provide real value 
 (except probably as an exercise in implementing abstract 
 programming theories from academia) nor is properly reinforced?
The question is what it takes to close every possible hole. .NET designers apparently decided not to close the reflection hole because the cost (in various senses) would be too high.
Oct 19 2013
parent Paulo Pinto <pjmlp progtools.org> writes:
Am 19.10.2013 17:09, schrieb Max Samukha:
 On Saturday, 19 October 2013 at 10:50:42 UTC, Maxim Fomin wrote:

 OK, you can remove extern(c) trick (however, it is not clear, why it
 shouldn't be counted as a type system hole) and you still have
 "reflection hole".

 I came up with the code in response to Andrei who said that
 constructor control flow is "primitive but quite adequate" and which
 "is already implemented and works". What "primitive but quite
 adequate" does mean is subjective, but it does not really prevent from
 what it is suppose to prevent. Of course in this case you do not
 corrupt memory or write to immutable (I am telling this for the third
 time). The point was made why would you have such constraint if it is
 easily avoidable? How much sense is in the constraint which does not
 provide real value (except probably as an exercise in implementing
 abstract programming theories from academia) nor is properly reinforced?
The question is what it takes to close every possible hole. .NET designers apparently decided not to close the reflection hole because the cost (in various senses) would be too high.
Actually it is very practical, even Java allows for the same functionality. The ability to disable the security manager and use reflection to access stuff one should actually not be aware of, is a very handy to do unit testing with badly designed libraries. For example, most Sitecore code uses static classes everywhere. So either you replicate the whole Sitecore API on both sides (consumer/producer code) to be able to mock all required classes. Or use dirty reflection tricks to rebind method calls, even for private ones. Too dirty I know, but enterprise code is never pretty. -- Paulo
Oct 19 2013
prev sibling next sibling parent reply Paulo Pinto <pjmlp progtools.org> writes:
Am 19.10.2013 00:29, schrieb Max Samukha:
 On Friday, 18 October 2013 at 20:03:22 UTC, Maxim Fomin wrote:

 (By the way, I don't see why the code above provoked you to C#
 talks).
Because you: 1) Mentioned C# as a safer alternative to D. 2) Are using reflection to demonstrate D's unsafety. Try this: using System; using System.Reflection; namespace test { class A { public int x; public A() { x += 1; } } class App { public static void Main (string[] args) { var a = new A(); var ctor = a.GetType().GetConstructor(new Type[] {}); ctor.Invoke(a, new object[] {}); ctor.Invoke(a, new object[] {}); Console.Write(a.x); } } }
There is nothing unsafe about this code snippet. -- Paulo
Oct 18 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 06:24:00 UTC, Paulo Pinto wrote:

 There is nothing unsafe about this code snippet.
Sure. There is nothing unsafe in misusing __traits and extern(C) as well.
Oct 18 2013
parent reply Paulo Pinto <pjmlp progtools.org> writes:
Am 19.10.2013 08:58, schrieb Max Samukha:
 On Saturday, 19 October 2013 at 06:24:00 UTC, Paulo Pinto wrote:

 There is nothing unsafe about this code snippet.
Sure. There is nothing unsafe in misusing __traits and extern(C) as well.
There is if the result is - memory corruption - memory leaks no longer visible to the GC - program crash - ...
Oct 19 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 07:02:21 UTC, Paulo Pinto wrote:
 Am 19.10.2013 08:58, schrieb Max Samukha:
 On Saturday, 19 October 2013 at 06:24:00 UTC, Paulo Pinto 
 wrote:

 There is nothing unsafe about this code snippet.
Sure. There is nothing unsafe in misusing __traits and extern(C) as well.
There is if the result is - memory corruption - memory leaks no longer visible to the GC - program crash - ...
No problem, since that was the programmer's explicit purpose. C# provides a ton of backdoors that could lead to what you mentioned in your list.
Oct 19 2013
next sibling parent reply Paulo Pinto <pjmlp progtools.org> writes:
Am 19.10.2013 09:12, schrieb Max Samukha:
 On Saturday, 19 October 2013 at 07:02:21 UTC, Paulo Pinto wrote:
 Am 19.10.2013 08:58, schrieb Max Samukha:
 On Saturday, 19 October 2013 at 06:24:00 UTC, Paulo Pinto wrote:

 There is nothing unsafe about this code snippet.
Sure. There is nothing unsafe in misusing __traits and extern(C) as well.
There is if the result is - memory corruption - memory leaks no longer visible to the GC - program crash - ...
No problem, since that was the programmer's explicit purpose. C# provides a ton of backdoors that could lead to what you mentioned in your list.
That is why they have to : - be marked unsafe - be allowed by the security manager In D's case it is no different, such code is only to be allowed in system code and partilly in thrusted. -- Paulo
Oct 19 2013
parent "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 07:22:35 UTC, Paulo Pinto wrote:

 That is why they have to :

 - be marked unsafe
 - be allowed by the security manager

 In D's case it is no different, such code is only to be allowed 
 in  system code and partilly in  thrusted.

 --
 Paulo
I understand. However, the case under discussion is about D failing to catch invalid constructor calls. In that regard, granted the C extern is marked trusted, D is no different than C#.
Oct 19 2013
prev sibling next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 19 October 2013 at 07:12:26 UTC, Max Samukha wrote:
 On Saturday, 19 October 2013 at 07:02:21 UTC, Paulo Pinto wrote:
 Am 19.10.2013 08:58, schrieb Max Samukha:
 On Saturday, 19 October 2013 at 06:24:00 UTC, Paulo Pinto 
 wrote:

 There is nothing unsafe about this code snippet.
Sure. There is nothing unsafe in misusing __traits and extern(C) as well.
There is if the result is - memory corruption - memory leaks no longer visible to the GC - program crash - ...
No problem, since that was the programmer's explicit purpose. C# provides a ton of backdoors that could lead to what you mentioned in your list.
This is wrong. Compare safe D and C# in safe, checked mode (I suspect you tried to sell unchecked mode, unmanaged pointers and C++ code invocation as unsafe C# - there are also unsafe features like casts or unions in unsafe D, but this is irrelevant, we are comparing safe mode) and try to come up with examples of memory corruption in C#. At least I showed 4 cases of memory corruption, 4 cases of broken immutable, 2 cases of broken purity in safe D without casts, unions and unchekeced attributes of extern C (which is also hole in type system). So far, you provided only resentment that D was negatively compred with C#.
Oct 19 2013
parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 07:39:36 UTC, Maxim Fomin wrote:
 This is wrong. Compare safe D and C# in safe, checked mode (I 
 suspect you tried to sell unchecked mode, unmanaged pointers 
 and C++ code invocation as unsafe C# - there are also unsafe 
 features like casts or unions in unsafe D, but this is 
 irrelevant, we are comparing safe mode) and try to come up with 
 examples of memory corruption in C#. At least I showed 4 cases 
 of memory corruption, 4 cases of broken immutable, 2 cases of 
 broken purity in safe D without casts, unions and unchekeced 
 attributes of extern C (which is also hole in type system). So 
 far, you provided only resentment that D was negatively compred 
 with C#.
I would agree if: 1. most of the cases you provided were not compiler bugs. 2. C#'s safety didn't have a price. 3. C# had immutable, pure, etc.
Oct 19 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 19 October 2013 at 08:21:18 UTC, Max Samukha wrote:
 On Saturday, 19 October 2013 at 07:39:36 UTC, Maxim Fomin wrote:
 This is wrong. Compare safe D and C# in safe, checked mode (I 
 suspect you tried to sell unchecked mode, unmanaged pointers 
 and C++ code invocation as unsafe C# - there are also unsafe 
 features like casts or unions in unsafe D, but this is 
 irrelevant, we are comparing safe mode) and try to come up 
 with examples of memory corruption in C#. At least I showed 4 
 cases of memory corruption, 4 cases of broken immutable, 2 
 cases of broken purity in safe D without casts, unions and 
 unchekeced attributes of extern C (which is also hole in type 
 system). So far, you provided only resentment that D was 
 negatively compred with C#.
I would agree if: 1. most of the cases you provided were not compiler bugs.
Wrong. Most of cases presented are frontend bugs, since all three known compilers share the same frontend, they are also buggy. In any case, D is not in a position like C, where there are plenty of compilers. Most are stack to dmd/gdc/ldc. So, there is no way to escape from this "just compiler bugs". You can throw "it is compiler bug, but not language issue" into the trash (please also D butthurt).
 2. C#'s safety didn't have a price.
I didn't heard that C# would advertise itself as having speed 'more than C' or any nonsense like D promises about its safety.
 3. C# had immutable, pure, etc.
But features which it does care to provide, are not bunch of holes in type system. This is so opposite to D with strings, shared, AAs, etc.
Oct 19 2013
next sibling parent reply "Max Samukha" <maxsamukha gmail.com> writes:
On Saturday, 19 October 2013 at 08:38:52 UTC, Maxim Fomin wrote:
 On Saturday, 19 October 2013 at 08:21:18 UTC, Max Samukha wrote:
 On Saturday, 19 October 2013 at 07:39:36 UTC, Maxim Fomin 
 wrote:
 This is wrong. Compare safe D and C# in safe, checked mode (I 
 suspect you tried to sell unchecked mode, unmanaged pointers 
 and C++ code invocation as unsafe C# - there are also unsafe 
 features like casts or unions in unsafe D, but this is 
 irrelevant, we are comparing safe mode) and try to come up 
 with examples of memory corruption in C#. At least I showed 4 
 cases of memory corruption, 4 cases of broken immutable, 2 
 cases of broken purity in safe D without casts, unions and 
 unchekeced attributes of extern C (which is also hole in type 
 system). So far, you provided only resentment that D was 
 negatively compred with C#.
I would agree if: 1. most of the cases you provided were not compiler bugs.
Wrong. Most of cases presented are frontend bugs, since all three known compilers share the same frontend, they are also buggy. In any case, D is not in a position like C, where there are plenty of compilers. Most are stack to dmd/gdc/ldc. So, there is no way to escape from this "just compiler bugs". You can throw "it is compiler bug, but not language issue" into the trash (please also D butthurt).
Note that you are making similar assumptions about the state of my butt as I did about your dissatisfaction.
 2. C#'s safety didn't have a price.
I didn't heard that C# would advertise itself as having speed 'more than C' or any nonsense like D promises about its safety.
I haven't heard D ever advertised itself as "faster than C". I heard that immutability/purity provides an opportunity for optimizations not possible in C, and those opportunities have not been realized yet.
 3. C# had immutable, pure, etc.
But features which it does care to provide, are not bunch of holes in type system. This is so opposite to D with strings, shared, AAs, etc.
What's wrong with D's strings?
Oct 19 2013
parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 19 October 2013 at 09:06:35 UTC, Max Samukha wrote:
 On Saturday, 19 October 2013 at 08:38:52 UTC, Maxim Fomin wrote:
 On Saturday, 19 October 2013 at 08:21:18 UTC, Max Samukha 
 wrote:
 On Saturday, 19 October 2013 at 07:39:36 UTC, Maxim Fomin 
 wrote:
 This is wrong. Compare safe D and C# in safe, checked mode 
 (I suspect you tried to sell unchecked mode, unmanaged 
 pointers and C++ code invocation as unsafe C# - there are 
 also unsafe features like casts or unions in unsafe D, but 
 this is irrelevant, we are comparing safe mode) and try to 
 come up with examples of memory corruption in C#. At least I 
 showed 4 cases of memory corruption, 4 cases of broken 
 immutable, 2 cases of broken purity in safe D without casts, 
 unions and unchekeced attributes of extern C (which is also 
 hole in type system). So far, you provided only resentment 
 that D was negatively compred with C#.
I would agree if: 1. most of the cases you provided were not compiler bugs.
Wrong. Most of cases presented are frontend bugs, since all three known compilers share the same frontend, they are also buggy. In any case, D is not in a position like C, where there are plenty of compilers. Most are stack to dmd/gdc/ldc. So, there is no way to escape from this "just compiler bugs". You can throw "it is compiler bug, but not language issue" into the trash (please also D butthurt).
Note that you are making similar assumptions about the state of my butt as I did about your dissatisfaction.
Right. This talks need to go away.
 2. C#'s safety didn't have a price.
I didn't heard that C# would advertise itself as having speed 'more than C' or any nonsense like D promises about its safety.
I haven't heard D ever advertised itself as "faster than C". I heard that immutability/purity provides an opportunity for optimizations not possible in C, and those opportunities have not been realized yet.
The point is shifted. The claim on D site pages are that it supports safe mode which disallows undefined behavior. Rebuttal are that this it not true - safe is currently broken due to 1) basing on static type rather than runtime which limits significantly ability to query which things are right and which things are not safe 2) because there are particular cases which shows safety breakages. (Why this is still relevant to the language and not only to compilers was discussed). It is bad to promise something which you are not able to deliver. In contrary (because C# was mentioned and thread engaged into comparison) C# when it claims to support safety, it actually support safety. Features which it cannot support, are not claimed to be supported. You mentioned performance, so I made a point that C# does not claim to be, for example, faster than C. Such claim does not make much sense, as much as claiming that D safe mode prevents from undefined behavior. It was used for comparison, not for claiming that D really claims to be faster than C.
 3. C# had immutable, pure, etc.
But features which it does care to provide, are not bunch of holes in type system. This is so opposite to D with strings, shared, AAs, etc.
What's wrong with D's strings?
Problem is that it uses char array of 1 byte to hold data which has size more than 1 byte. It was discussed in "Inconsistency" thread (http://forum.dlang.org/thread/hoopiiobddbapybbwwoc forum.dlang.org).
Oct 19 2013
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10/19/2013 10:38 AM, Maxim Fomin wrote:
 1. most of the cases you provided were not compiler bugs.
Wrong. Most of cases presented are frontend bugs, since all three known compilers share the same frontend, they are also buggy.
Keeping being technically incorrect just does not help the discussion. I don't think I _actually_ disagree with you on any major points, but it is hard to judge.
 In any case, D is not in a position like C, where there are plenty
 of compilers. Most are stack to dmd/gdc/ldc. So, there is no way
 to escape from this "just compiler bugs". You can throw "it is
 compiler bug, but not language issue" into ...
Just use the proper terms, and you will be understood.
Oct 19 2013
prev sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 19 October 2013 at 07:12:26 UTC, Max Samukha wrote:
 No problem, since that was the programmer's explicit purpose. 
 C# provides a ton of backdoors that could lead to what you 
 mentioned in your list.
So, no cases of memory errors in safe mode of C#? This is what was expected.
Oct 19 2013
prev sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 18 October 2013 at 22:29:45 UTC, Max Samukha wrote:
 On Friday, 18 October 2013 at 20:03:22 UTC, Maxim Fomin wrote:

 (By the way, I don't see why the code above provoked you to C#
 talks).
Because you: 1) Mentioned C# as a safer alternative to D.
So, what? If I happen in some another context to mention COBOL, would you bother to remember this and show some piece of COBOL code which is supposedly unsafe or avoids some formal limititation? OK.
 2) Are using reflection to demonstrate D's unsafety.
Actually aggregate name of collection was "(collection of memory errors, type system breakages and other cases to shoot your foot provided by bugzilla issues, me and other people)". It doesn't mean that each example shows memory error bug. Obviously this case doesn't show unsafity, it shows that the limitation imposed on the language is arbitrary and groundless.
Oct 19 2013