Thread overview | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 18, 2015 I have made a discovery | ||||
---|---|---|---|---|
| ||||
The following code almost compiles. -------- import core.stdc.stdlib; class Foo : Exception { @nogc pure nothrow @safe this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) { super(msg, file, line, next); } @nogc new(size_t size) { return malloc(size); } } @nogc void main() { throw new Foo("Oh no!"); } -------- That's right. An unofficially deprecated feature of the language and a newer feature of the language coming together in an interesting way. The only thing stopping this code from actually working is a trivial change to druntime to mark the Throwable, Exception, and Error constructors as @nogc, which I just created a pull request for directly through GitHub. https://github.com/D-Programming-Language/druntime/pull/1223 Now imagine that instead of just a malloc which leaks memory like the above, other allocation schemes are used here instead. Consider also the coming addition to the language for class reference counting methods opAddRef and opRelease. Then let your imagination run wild. Enjoy! |
April 18, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | I *think* my PR might have also led me to discovering some kind of DMD bug to do with not being able to call a @nogc super class constructor from a constructor which isn't @nogc. It could be something else entirely, but it caused some undefined reference bugs to appear, which is odd. |
April 18, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On Saturday, 18 April 2015 at 15:39:05 UTC, w0rp wrote:
> I *think* my PR might have also led me to discovering some kind of DMD bug to do with not being able to call a @nogc super class constructor from a constructor which isn't @nogc. It could be something else entirely, but it caused some undefined reference bugs to appear, which is odd.
Disregard that, I needed to change the .di file too...
|
April 19, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On 19/04/2015 3:24 a.m., w0rp wrote:
> The following code almost compiles.
>
> --------
> import core.stdc.stdlib;
>
> class Foo : Exception {
> @nogc pure nothrow @safe
> this(string msg, string file = __FILE__, size_t line = __LINE__,
> Throwable next = null) {
> super(msg, file, line, next);
> }
>
> @nogc
> new(size_t size) {
> return malloc(size);
> }
> }
>
> @nogc
> void main() {
> throw new Foo("Oh no!");
> }
> --------
>
> That's right. An unofficially deprecated feature of the language and a
> newer feature of the language coming together in an interesting way. The
> only thing stopping this code from actually working is a trivial change
> to druntime to mark the Throwable, Exception, and Error constructors as
> @nogc, which I just created a pull request for directly through GitHub.
>
> https://github.com/D-Programming-Language/druntime/pull/1223
>
> Now imagine that instead of just a malloc which leaks memory like the
> above, other allocation schemes are used here instead. Consider also the
> coming addition to the language for class reference counting methods
> opAddRef and opRelease. Then let your imagination run wild.
>
> Enjoy!
Awesome! Although we may need to "undeprecate" that feature.
|
April 19, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole Attachments: | On Sun, 19 Apr 2015 12:29:45 +1200, Rikki Cattermole wrote: > Awesome! Although we may need to "undeprecate" that feature. as it is not generating deprecation warning now, it should be fairly easy: just reintroduce it into specs. i can see why it was deprecated in the first place, but it's much easier to simply write "new Exception" instead of "allocateWithMyCoolScheme!Exception". |
April 19, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:
> On Sun, 19 Apr 2015 12:29:45 +1200, Rikki Cattermole wrote:
>
>> Awesome! Although we may need to "undeprecate" that feature.
>
> as it is not generating deprecation warning now, it should be fairly
> easy: just reintroduce it into specs. i can see why it was deprecated in
> the first place, but it's much easier to simply write "new Exception"
> instead of "allocateWithMyCoolScheme!Exception".
maybe I'm dumb in asking this, but if there was already an API for allocators in D... why is a std.allocator not being written ontop of it?
it seems much more elegant to begin with.
|
April 19, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:
> On Sun, 19 Apr 2015 12:29:45 +1200, Rikki Cattermole wrote:
>
>> Awesome! Although we may need to "undeprecate" that feature.
>
> as it is not generating deprecation warning now, it should be fairly
> easy: just reintroduce it into specs. i can see why it was deprecated in
> the first place, but it's much easier to simply write "new Exception"
> instead of "allocateWithMyCoolScheme!Exception".
If you overload a class's `new`, you are deciding for your class's user how it will be allocated. I think it's better to let the programmer decide how they want the class to be allocated.
|
April 19, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brian Schott | On Sunday, 19 April 2015 at 01:19:47 UTC, Brian Schott wrote:
> If you overload a class's `new`, you are deciding for your class's user how it will be allocated.
Without telling them btw. (Well, except the documentation or the source.) So now, they new it and expect the GC to clean it up like any other class.... but that invisibly doesn't happen.
Overriding new was totally a misfeature in D and it should go away.
BTW having new in the language at all I wish wasn't a thing. Perhaps it was right back in old D1, but not ideal in D2, where we can easily define a template to do it - which could be easily swapped out at the usage point and enable all kinds of nice things.
Of course, we can still define library New!T (and indeed, I think we should), but the keyword will always have a bit of a brainspace edge over it...
|
April 19, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Sunday, 19 April 2015 at 00:39:03 UTC, ketmar wrote:
> but it's much easier to simply write "new Exception" instead of "allocateWithMyCoolScheme!Exception".
eh i would just call it "New!Exception" where the cool scheme is in the module name. So you "import mycoolscheme;" which defines the New.
Then you can disambiguate with the usual module features if you use two schemes in the same scope. It'd be so beautiful.
|
April 19, 2015 Re: I have made a discovery | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On 19/04/2015 1:52 p.m., Adam D. Ruppe wrote:
> On Sunday, 19 April 2015 at 01:19:47 UTC, Brian Schott wrote:
>> If you overload a class's `new`, you are deciding for your class's
>> user how it will be allocated.
>
>
> Without telling them btw. (Well, except the documentation or the
> source.) So now, they new it and expect the GC to clean it up like any
> other class.... but that invisibly doesn't happen.
>
> Overriding new was totally a misfeature in D and it should go away.
>
>
> BTW having new in the language at all I wish wasn't a thing. Perhaps it
> was right back in old D1, but not ideal in D2, where we can easily
> define a template to do it - which could be easily swapped out at the
> usage point and enable all kinds of nice things.
>
> Of course, we can still define library New!T (and indeed, I think we
> should), but the keyword will always have a bit of a brainspace edge
> over it...
auto adding(int x, int y) {
int[3] values = allocate!(int[3]);
values[0] = x;
values[1] = y;
values[2] = x + y;
return values;
}
...
auto adding(int x, int y) {
int[3] values = new!(int[3]);
values[0] = x;
values[1] = y;
values[2] = x + y;
return values;
}
...
auto adding(int x, int y) {
int[3] values = new int[](3);
values[0] = x;
values[1] = y;
values[2] = x + y;
return values;
}
...
struct MyAllocator {
T* opAllocate(T)(){
T* value;
// alloc
value.rtInfo.fromGC = false;
value.rtInfo.isRefCounted = false;
value.rtInfo.isGCFree = true; // allows GC to free it
value.rtInfo.freeFunction = &opFree; // maybe?
return value;
}
void opFree(T)(T*){
// free
}
}
new(MyAllocator):
auto adding(int x, int y) {
int[3] values = new int[](3);
values[0] = x;
values[1] = y;
values[2] = x + y;
return values;
}
...
I'm not totally sold.
|
Copyright © 1999-2021 by the D Language Foundation