View mode: basic / threaded / horizontal-split · Log in · Help
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++?
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++?
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++?
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++?
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++?
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++?
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++?
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++?
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++?
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
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home