Thread overview | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 16, 2012 Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Hi, I have a few questions about D and could use some help. For instance, how can i rebuild such a behavior? class Foo { public: Foo(const Bar& b) { At C++ you can ensure that a reference is requested and must not null. Nevertheless lvalues are functional, which means Foo(Bar(42)) would operate just as good as Bar b(42); Foo(b); The same procedure doesn't seem to operate with const ref, instead you can only use ref. But in this case Ivalues doesn't operate. Because of the fact that in D all objects are indication of references I thought that I simply didn't need a storage class. But then I recognized that at my D equivalent… class Foo { public: this(Bar b) { …null can also be passed. That case I would like to prevent, but at the same time allow Ivalues. How does that work in D classes? As far as I know this operates with structs, but shouldn't it be possible with classes and objects too? Would be really nice if anyone had an advice for me. |
April 16, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace Attachments:
| On Apr 16, 2012 5:29 PM, "Namespace" <rswhite4@googlemail.com> wrote:
> That case I would like to prevent, but at the same time allow
> Ivalues. How does that work in D classes?
> As far as I know this operates with structs, but shouldn't it be
> possible with classes and objects too?
I would recommend a precondition. It is a language enforced method of restricting what values may be passed into a function. If the code is compiled for release the checks are not included and do not cost anything.
|
April 16, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On 04/16/2012 11:25 PM, Namespace wrote:
> Hi,
>
> I have a few questions about D and could use some help. For
> instance, how can i rebuild such a behavior?
>
> class Foo {
> public:
> Foo(const Bar& b) {
>
> At C++ you can ensure that a reference is requested and must not
> null.
> Nevertheless lvalues are functional, which means Foo(Bar(42))
> would operate just as good as
> Bar b(42);
> Foo(b);
>
> The same procedure doesn't seem to operate with const ref,
> instead you can only use ref. But in this case Ivalues doesn't
> operate.
> Because of the fact that in D all objects are indication of
> references I thought that I simply didn't need a storage class.
> But then I recognized that at my D equivalent…
>
> class Foo {
> public:
> this(Bar b) {
>
>
> …null can also be passed.
>
> That case I would like to prevent, but at the same time allow
> Ivalues. How does that work in D classes?
> As far as I know this operates with structs, but shouldn't it be
> possible with classes and objects too?
>
> Would be really nice if anyone had an advice for me.
You could do this:
this(Bar b)in{assert(b !is null);}body{
|
April 16, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | Namespace:
> how can i rebuild such a behavior?
>
> class Foo {
> public:
> Foo(const Bar& b) {
In D struct instances are values, and you can manage them as values, or as a pointer to value (or pointer to pointer to value, etc). In D class instances are always managed by reference, and such references, like pointers, can be null (and emplace() is supposed to allow in-place allocation of a class instance).
So in normal D code you can't write D code equivalent to that C++ code. Some possibilities:
class Foo {}
void bar(Foo f) {}
void bar(const Foo f) {}
struct Baz {}
void spam(Baz b) {}
void spam(in Baz b) {}
void spam(ref Baz b) {}
void spam(Baz* b) {}
void spam(const Baz* b) {}
void spam(const ref Baz b) {}
void spam(immutable ref Baz b) {}
There is also inout, out, etc.
Lot of people (me too) have asked non-null class references (and pointers) in D. We are now able to @disable some constructors...
Bye,
bearophile
|
April 16, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | This is what I am actually doing at the moment, but I thougth that in a modern language like D, it is possible to have non-null references to avoid such constructs with assert.
My last hope was that an explicit ref would allow me both: non-null references _and_ lvalues, at least for objects.
That is very sad. Any possibility that this might change?
I really like that objects are implicit references and so i would not use structs, but it looks like i have no choice if i would avoid asserts..
On Monday, 16 April 2012 at 21:34:34 UTC, Timon Gehr wrote:
> On 04/16/2012 11:25 PM, Namespace wrote:
>> Hi,
>>
>> I have a few questions about D and could use some help. For
>> instance, how can i rebuild such a behavior?
>>
>> class Foo {
>> public:
>> Foo(const Bar& b) {
>>
>> At C++ you can ensure that a reference is requested and must not
>> null.
>> Nevertheless lvalues are functional, which means Foo(Bar(42))
>> would operate just as good as
>> Bar b(42);
>> Foo(b);
>>
>> The same procedure doesn't seem to operate with const ref,
>> instead you can only use ref. But in this case Ivalues doesn't
>> operate.
>> Because of the fact that in D all objects are indication of
>> references I thought that I simply didn't need a storage class.
>> But then I recognized that at my D equivalent…
>>
>> class Foo {
>> public:
>> this(Bar b) {
>>
>>
>> …null can also be passed.
>>
>> That case I would like to prevent, but at the same time allow
>> Ivalues. How does that work in D classes?
>> As far as I know this operates with structs, but shouldn't it be
>> possible with classes and objects too?
>>
>> Would be really nice if anyone had an advice for me.
>
> You could do this:
>
> this(Bar b)in{assert(b !is null);}body{
|
April 17, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | Now i have something like this. It works and manipulates lvalues so that i can pass my objects by ref to except null. But is this smart? class Bar { public: int x; static ref Bar opCall(int x) { static Bar b; b = new Bar(x); return b; } this(int x) { this.x = x; } } class Foo { private: Bar _bar; public: int y; this() { } this(ref Bar b) { //assert(b !is null); writefln("B.x %d", b.x); } } Bar b = new Bar(42); new Foo(b); // works new Foo(null); // compiler error new Foo(Bar(23)); // works new Foo(Bar(25)); // works |
April 17, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Tuesday, 17 April 2012 at 08:02:02 UTC, Namespace wrote:
> Now i have something like this. It works and manipulates lvalues so that i can pass my objects by ref to except null.
>
> But is this smart?
>
> class Bar {
> public:
> int x;
>
> static ref Bar opCall(int x) {
> static Bar b;
>
> b = new Bar(x);
>
> return b;
> }
>
> this(int x) {
> this.x = x;
> }
> }
>
> class Foo {
> private:
> Bar _bar;
>
> public:
> int y;
>
> this() { }
>
> this(ref Bar b) {
> //assert(b !is null);
>
> writefln("B.x %d", b.x);
> }
> }
>
> Bar b = new Bar(42);
>
> new Foo(b); // works
> new Foo(null); // compiler error
> new Foo(Bar(23)); // works
> new Foo(Bar(25)); // works
But if I write
Bar bn;
new Foo(bn);
it works also and doesn't throw a compiler error.
To avoid this, I have to write an assert(obj !is null); again.
This really sucks. If anybody else works with my Code and puts a null reference to any method he gets no compiler error and wonder why he gets a runtime error instead.
Thats very annoying...
|
April 17, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On Tuesday, 17 April 2012 at 09:39:10 UTC, Namespace wrote:
> On Tuesday, 17 April 2012 at 08:02:02 UTC, Namespace wrote:
>> Now i have something like this. It works and manipulates lvalues so that i can pass my objects by ref to except null.
>>
>> But is this smart?
>>
>> class Bar {
>> public:
>> int x;
>>
>> static ref Bar opCall(int x) {
>> static Bar b;
>>
>> b = new Bar(x);
>>
>> return b;
>> }
>>
>> this(int x) {
>> this.x = x;
>> }
>> }
>>
>> class Foo {
>> private:
>> Bar _bar;
>>
>> public:
>> int y;
>>
>> this() { }
>>
>> this(ref Bar b) {
>> //assert(b !is null);
>>
>> writefln("B.x %d", b.x);
>> }
>> }
>>
>> Bar b = new Bar(42);
>>
>> new Foo(b); // works
>> new Foo(null); // compiler error
>> new Foo(Bar(23)); // works
>> new Foo(Bar(25)); // works
>
>
> But if I write
>
> Bar bn;
> new Foo(bn);
>
> it works also and doesn't throw a compiler error.
> To avoid this, I have to write an assert(obj !is null); again.
> This really sucks. If anybody else works with my Code and puts a null reference to any method he gets no compiler error and wonder why he gets a runtime error instead.
> Thats very annoying...
For that, you have static if contitions, and indeed you can make it a compile-time error.
|
April 17, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | On 04/17/2012 02:39 AM, Namespace wrote: >> Bar b = new Bar(42); >> >> new Foo(b); // works >> new Foo(null); // compiler error That fails because null is a compile time value and you have a special template code for that that fails the compilation. >> new Foo(Bar(23)); // works >> new Foo(Bar(25)); // works > > > But if I write > > Bar bn; > new Foo(bn); > > it works also and doesn't throw a compiler error. There, bn is a variable that has it's own life at runtime. Although the compiler can analyze the code to determine that bn never becomes anything but null, we may not want it to be too smart. Imagine that there are lines after Bar bn; that you have just commented out: Bar bn; // bn = foo(); new Foo(bn); Now the compilation would failure would be an annoyance. That's part of the reason why the compiler does not go that deep in its analysis. > To avoid this, I have to write an assert(obj !is null); again. Yes, you must because whetheer obj is null is only known at runtime. > This really sucks. If anybody else works with my Code and puts a null > reference to any method he gets no compiler error and wonder why he gets > a runtime error instead. > Thats very annoying... Ali |
April 17, 2012 Re: Aquivalent References as in C++? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 04/17/2012 08:49 AM, Ali Çehreli wrote: > That fails because null is a compile time value and you have a special > template code for that that fails the compilation. Scratch the 'template' part. You don't have templates there but what I said is still valid. Basically, you have some code that fails at compile time. Ali |
Copyright © 1999-2021 by the D Language Foundation