digitalmars.D - Recursive attribute for virtual functions?
- 12345swordy (19/19) Mar 27 2018 For example
- ag0aep6g (6/15) Mar 27 2018 [...]
- 12345swordy (3/19) Mar 27 2018 Then explain this then.
- ag0aep6g (3/5) Mar 27 2018 B.talk is @safe. The compiler ignores the @system attribute on B.talk,
- 12345swordy (2/7) Mar 27 2018 Shouldn't it give a warning then?
- ag0aep6g (3/4) Mar 27 2018 I wouldn't mind a warning, or even an error. Putting both @safe and
- arturg (28/32) Mar 27 2018 shouldn't it create a overload?
- ag0aep6g (16/36) Mar 27 2018 I don't think so. As far as I know, you can't overload on attributes.
- Jonathan M Davis (22/30) Mar 27 2018 Warnings are almost always a terrible idea, since it's bad practice to l...
- bauss (8/29) Mar 28 2018 Your actual test should have been like this:
For example class A { recursive safe void talk() { writeln("Hi"); } } class B : A { override void talk() // safe attribute added by recursive attribute and can not be removed { writeln("Bye"); } } I have notice that potential bugs can slip by the compiler during compile time, and I purpose this as way to counter them. Alex
Mar 27 2018
On 03/27/2018 10:39 PM, 12345swordy wrote:class A { recursive safe void talk()[...]} class B : A { override void talk() // safe attribute added by recursive attribute and can not be removed[...]}It already works like that. B.talk is safe, and you can't make it system. You can mark it as system, that gets overridden by A.talk's safe. https://run.dlang.io/is/BlH8bp
Mar 27 2018
On Tuesday, 27 March 2018 at 20:49:25 UTC, ag0aep6g wrote:On 03/27/2018 10:39 PM, 12345swordy wrote:Then explain this then. https://run.dlang.io/is/S2KLs5class A { recursive safe void talk()[...]} class B : A { override void talk() // safe attribute added by recursive attribute and can not be removed[...]}It already works like that. B.talk is safe, and you can't make it system. You can mark it as system, that gets overridden by A.talk's safe. https://run.dlang.io/is/BlH8bp
Mar 27 2018
On 03/27/2018 11:02 PM, 12345swordy wrote:Then explain this then. https://run.dlang.io/is/S2KLs5B.talk is safe. The compiler ignores the system attribute on B.talk, because A.talk's safe attribute takes precedence.
Mar 27 2018
On Tuesday, 27 March 2018 at 21:05:32 UTC, ag0aep6g wrote:On 03/27/2018 11:02 PM, 12345swordy wrote:Shouldn't it give a warning then?Then explain this then. https://run.dlang.io/is/S2KLs5B.talk is safe. The compiler ignores the system attribute on B.talk, because A.talk's safe attribute takes precedence.
Mar 27 2018
On 03/27/2018 11:10 PM, 12345swordy wrote:Shouldn't it give a warning then?I wouldn't mind a warning, or even an error. Putting both safe and system directly on a function is an error, too.
Mar 27 2018
On Tuesday, 27 March 2018 at 21:25:33 UTC, ag0aep6g wrote:On 03/27/2018 11:10 PM, 12345swordy wrote:shouldn't it create a overload? for example this fails: class A { void talk() safe {} } class B : A { alias talk = A.talk; void talk() system {} } but this works: class A { void talk() {} } class B : A { alias talk = A.talk; void talk(int) {} } this works also: class C { void talk() system {} void talk() safe {} }Shouldn't it give a warning then?I wouldn't mind a warning, or even an error. Putting both safe and system directly on a function is an error, too.
Mar 27 2018
On 03/28/2018 12:19 AM, arturg wrote:shouldn't it create a overload?I don't think so. As far as I know, you can't overload on attributes. [...]but this works: class A { void talk() {} } class B : A { alias talk = A.talk; void talk(int) {} }Because different parameters make overloads.this works also: class C { void talk() system {} void talk() safe {} }DMD might accept that, but I don't think it works in a meaningful way. How do you call the system one? Looks like the safe one will always be called, even from system code: ---- import std.stdio; void talk() system { writeln(" system"); } void talk() safe { writeln(" safe"); } void main() system { talk(); /* Prints " safe". */ } ----
Mar 27 2018
On Tuesday, 27 March 2018 at 23:23:38 UTC, ag0aep6g wrote:DMD might accept that, but I don't think it works in a meaningful way. How do you call the system one? Looks like the safe one will always be called, even from system code: ---- import std.stdio; void talk() system { writeln(" system"); } void talk() safe { writeln(" safe"); } void main() system { talk(); /* Prints " safe". */ } ----you can call them with __traits(getOverloads, T, "name")[index]; you can overload on types attributes and linkage, but seems like you can only merge overloads based on types.
Mar 27 2018
On Tuesday, 27 March 2018 at 23:34:20 UTC, arturg wrote:On Tuesday, 27 March 2018 at 23:23:38 UTC, ag0aep6g wrote:i have some templates which can be used like this: type.dgAt!("name", index); dgAt!("name", index, somemodule); dgAt!("name", index, "somemodule"); alias fun = aAt!("name", index, someTypeOrModule); type.dgOf!("name", void function(int) safe); dgOf!("name", void function(int) safe, module); dgOf!("name", void function(int) safe, "module"); from!(type, "name").aAt!1; from!(type, "name").aOf!(void function(int)); from!(type, "name").dgAt!1; from!(type, "name").dgOf!(void function(int)); but this fails: type.dgOf!("name", extern(C) void function(int) safe); and this works: alias funtype = extern(C) void function(int) safe; type.dgOf!("name", funtype);DMD might accept that, but I don't think it works in a meaningful way. How do you call the system one? Looks like the safe one will always be called, even from system code: ---- import std.stdio; void talk() system { writeln(" system"); } void talk() safe { writeln(" safe"); } void main() system { talk(); /* Prints " safe". */ } ----you can call them with __traits(getOverloads, T, "name")[index]; you can overload on types attributes and linkage, but seems like you can only merge overloads based on types.
Mar 27 2018
On 03/28/2018 01:34 AM, arturg wrote:you can call them with __traits(getOverloads, T, "name")[index]; you can overload on types attributes and linkage, but seems like you can only merge overloads based on types.I don't think there's value in allowing overloads that can only be called via __traits. Looks like this is an old issue [1] that is currently being fixed. run.dlang.io's "beta" and "nightly" compilers don't accept such overloads [2]. But I can't reproduce that locally. The fix has apparently been reverted because it needs more work. [1] https://issues.dlang.org/show_bug.cgi?id=2789 [2] https://run.dlang.io/is/qlyMti
Mar 27 2018
On Tuesday, March 27, 2018 21:10:25 12345swordy via Digitalmars-d wrote:On Tuesday, 27 March 2018 at 21:05:32 UTC, ag0aep6g wrote:Warnings are almost always a terrible idea, since it's bad practice to leave warnings in place, meaning that it's effectively the same as an error except that it doesn't force folks to fix the problem immediately, and thanks to -w, it effectively forks the language, because stuff like is expressions and which template constraints pass or not can change based on whether -w is used or not. IMHO, it was a huge mistake to ever add warnings to the compiler. So, if we were going to do something with this, it should be an error, not a warning. In most cases, D ignores attributes that don't apply, which is sometimes annoying, but it can be very handy in generic code. It can also be helpful when an attribute is applied with : or {}. So, it's not particularly surprising that the compiler would ignore the attribute in this case. That being said, at the moment, I can't think of any reason why it would be beneficial to allow marking a derived function with system directly when the base class function is safe. Marking it with trusted is often valuable, because in that case, the derived function is doing something that's system, but the programmer has validated that it's safe, so it doesn't violate the API of the base class. So, you wouldn't want to treat it like you would a function that was directly marked with safe trusted, but that doesn't mean that system couldn't be disallowed. - Jonathan M DavisOn 03/27/2018 11:02 PM, 12345swordy wrote:Shouldn't it give a warning then?Then explain this then. https://run.dlang.io/is/S2KLs5B.talk is safe. The compiler ignores the system attribute on B.talk, because A.talk's safe attribute takes precedence.
Mar 27 2018
On Tuesday, 27 March 2018 at 21:02:11 UTC, 12345swordy wrote:On Tuesday, 27 March 2018 at 20:49:25 UTC, ag0aep6g wrote:Your actual test should have been like this: https://run.dlang.io/is/nF9dQk And as you can see it gives an error. You wouldn't be able to do anything that's not safe, so it wouldn't really matter. As soon as you attempted to do something else the compiler would yield an error.On 03/27/2018 10:39 PM, 12345swordy wrote:Then explain this then. https://run.dlang.io/is/S2KLs5class A { recursive safe void talk()[...]} class B : A { override void talk() // safe attribute added by recursive attribute and can not be removed[...]}It already works like that. B.talk is safe, and you can't make it system. You can mark it as system, that gets overridden by A.talk's safe. https://run.dlang.io/is/BlH8bp
Mar 28 2018