digitalmars.D - Pointers vs. References
- Michael Neumann (22/22) Jun 13 2007 Hi,
- Lionello Lunesu (12/25) Jun 13 2007 That's not a bug.
- Dan (2/31) Jun 13 2007 Heh... using classes in any language will cut your performance compared ...
- Daniel Keep (3/12) Jun 13 2007 Odd; last time I looked at disassembled machine code that used
- BCS (8/23) Jun 13 2007 class Foo
- Michael Neumann (11/43) Jun 13 2007 Thanks for all your answers.
- Bill Baxter (5/35) Jun 13 2007 This issue comes up frequently enough that I'm starting to think "check
- Ary Manzana (11/15) Jun 13 2007 Can't writing
- Jarrett Billingsley (4/12) Jun 13 2007 I don't think the compiler should rewrite it, but I don't think it shoul...
- Georg Wrede (9/30) Jun 13 2007 Count me in.
- OF (2/9) Jun 13 2007 Count me in too. I've had problems with this. At least a warning would b...
- Extrawurst (3/12) Jun 13 2007 definitely ! i ran into this very often and i know many D beginners who
- Georg Wrede (31/46) Jun 13 2007 Actually, why do we use the foo !is null idiom at all? (Or try to use
- Jarrett Billingsley (11/17) Jun 13 2007 Except there's one tiny inconsistency in the language.
- Georg Wrede (40/63) Jun 13 2007 Geez!!!
- Kristian Kilpi (5/14) Jun 14 2007 On Wed, 13 Jun 2007 23:32:10 +0300, Jarrett Billingsley
- Bill Baxter (15/38) Jun 13 2007 Why not have the compiler just rewrite all equality comparisons on class...
- Myron Alexander (10/13) Jun 13 2007 I prefer that the compiler does not rewrite my code.
- Bill Baxter (6/20) Jun 13 2007 But '==' *does* work differently for different types. Already.
- Myron Alexander (3/4) Jun 14 2007 Sorry. What I meant is that is has the same semantics. When you see ==,
- Oskar Linde (5/10) Jun 14 2007 One could argue that = should be analogous to ==. I.e, if = assigns
- Regan Heath (7/18) Jun 14 2007 One could also argue that the value of a class reference is the memory a...
-
Kristian Kilpi
(34/37)
Jun 14 2007
On Wed, 13 Jun 2007 10:09:24 +0300, Michael Neumann
... - Michael Neumann (6/16) Jun 14 2007 Thanks.
- Robert Fraser (6/11) Jun 14 2007 Here's one: say you have a clas Wrapper that wraps another class. You mi...
Hi, What I find confusing in D is the difference between references and pointers. References server somehow the same purpose. What are the impacts on using references instead of pointers? (e.g. Neuron instead of Neuron*). Is there some GC magic involved for references? I've ported a pulsed neuronal network simulator from C++ to see how it behaves performance wise in D, but there must be really something wrong in D (or in my implementation), as it's at least 4x slower (and when the datasets grow, it takes infinitively long time). And I guess I also found a bug in gdc: Synapse x = ...; while (x != null) { } This segfaults, while: Synapse x = ... while (!(x is null)) { } does not. Best regards, Michael
Jun 13 2007
Michael Neumann wrote:Synapse x = ...; while (x != null) { } This segfaults, while: Synapse x = ... while (!(x is null)) { } does not.That's not a bug. '==' and '!=' result in a call to opEquals, which is likely to segfault when one of the operands is null. You should use 'is' or in your case '!is'. while (x !is null) { } As for your question about references. A reference is basically the same as a pointer, so there should be no performance difference between the two. Without more details, it's hard to say what could be the reason behind the bad performance. L.
Jun 13 2007
Lionello Lunesu Wrote:Michael Neumann wrote:Heh... using classes in any language will cut your performance compared to using structs. D has nice structs. References are pointers to pointers to something; not "the same". Also, using while(x !is null) after explicitly defining it is usually wrong; you usually want do { ... } while(x !is null); That's all I can gather though from your vague post.Synapse x = ...; while (x != null) { } This segfaults, while: Synapse x = ... while (!(x is null)) { } does not.That's not a bug. '==' and '!=' result in a call to opEquals, which is likely to segfault when one of the operands is null. You should use 'is' or in your case '!is'. while (x !is null) { } As for your question about references. A reference is basically the same as a pointer, so there should be no performance difference between the two. Without more details, it's hard to say what could be the reason behind the bad performance. L.
Jun 13 2007
Odd; last time I looked at disassembled machine code that used references, they sure as hell looked like pointers... -- DanielAs for your question about references. A reference is basically the same as a pointer, so there should be no performance difference between the two. Without more details, it's hard to say what could be the reason behind the bad performance. L.Heh... using classes in any language will cut your performance compared to using structs. D has nice structs. References are pointers to pointers to something; not "the same". Also, using while(x !is null) after explicitly defining it is usually wrong; you usually want do { ... } while(x !is null); That's all I can gather though from your vague post.
Jun 13 2007
Daniel Keep wrote:class Foo { } Foo ref; // reference (pointer) to object Foo* ptr; // pointer to reference (pointer) to object The point that should be remembered is that objects already have reference semantics and classType* is almost never of any use.Odd; last time I looked at disassembled machine code that used references, they sure as hell looked like pointers... -- DanielAs for your question about references. A reference is basically the same as a pointer, so there should be no performance difference between the two. Without more details, it's hard to say what could be the reason behind the bad performance. L.Heh... using classes in any language will cut your performance compared to using structs. D has nice structs. References are pointers to pointers to something; not "the same". Also, using while(x !is null) after explicitly defining it is usually wrong; you usually want do { ... } while(x !is null); That's all I can gather though from your vague post.
Jun 13 2007
Dan wrote:Lionello Lunesu Wrote:Thanks for all your answers. Well, the C++ version of course uses classes as well. It's a literal translation from C++ to D. For those interested, the source is available via my mercurial repository at: http://ntecs.de/hg-projects/inspire/ (branch "d"). hg clone static-http://ntecs.de/hg-projects/inspire/ cd inspire hg update -C d Regards, MichaelMichael Neumann wrote:Heh... using classes in any language will cut your performance compared to using structs. D has nice structs. References are pointers to pointers to something; not "the same". Also, using while(x !is null) after explicitly defining it is usually wrong; you usually want do { ... } while(x !is null); That's all I can gather though from your vague post.Synapse x = ...; while (x != null) { } This segfaults, while: Synapse x = ... while (!(x is null)) { } does not.That's not a bug. '==' and '!=' result in a call to opEquals, which is likely to segfault when one of the operands is null. You should use 'is' or in your case '!is'. while (x !is null) { } As for your question about references. A reference is basically the same as a pointer, so there should be no performance difference between the two. Without more details, it's hard to say what could be the reason behind the bad performance. L.
Jun 13 2007
Lionello Lunesu wrote:Michael Neumann wrote:This issue comes up frequently enough that I'm starting to think "check against null literal" should maybe be special cased. It even bites me from time to time and I know what I'm supposed to do. --bbSynapse x = ...; while (x != null) { } This segfaults, while: Synapse x = ... while (!(x is null)) { } does not.That's not a bug. '==' and '!=' result in a call to opEquals, which is likely to segfault when one of the operands is null. You should use 'is' or in your case '!is'. while (x !is null) { } As for your question about references. A reference is basically the same as a pointer, so there should be no performance difference between the two. Without more details, it's hard to say what could be the reason behind the bad performance. L.
Jun 13 2007
Lionello Lunesu escribió:That's not a bug. '==' and '!=' result in a call to opEquals, which is likely to segfault when one of the operands is null. You should use 'is' or in your case '!is'.Can't writing x == null, x != null be rewritten by the compiler to x is null, x !is null ? I think the two firsts will always segfault. When would a user want to segfault her program? Or, better asked, when would a user want to do x == null? Regards, Ary
Jun 13 2007
"Ary Manzana" <ary esperanto.org.ar> wrote in message news:f4ombu$16mp$1 digitalmars.com...Can't writing x == null, x != null be rewritten by the compiler to x is null, x !is null ? I think the two firsts will always segfault. When would a user want to segfault her program? Or, better asked, when would a user want to do x == null?I don't think the compiler should rewrite it, but I don't think it should be allowed either. Either make it a warning or an error to ==/!= to null.
Jun 13 2007
Jarrett Billingsley wrote:"Ary Manzana" <ary esperanto.org.ar> wrote in message news:f4ombu$16mp$1 digitalmars.com...Count me in. While I'd prefer to use x == null, I can understand that it may be bad from a language design point. It would create an anomaly (because it artificially avoids calling a member function) which is misleading and requires one to remember it when reasoning about the language. So, instead, it should not be allowed. It should be an error. It is a construct the programmer didn't intend to write. :-) And which will bite him, period.Can't writing x == null, x != null be rewritten by the compiler to x is null, x !is null ? I think the two firsts will always segfault. When would a user want to segfault her program? Or, better asked, when would a user want to do x == null?I don't think the compiler should rewrite it, but I don't think it should be allowed either. Either make it a warning or an error to ==/!= to null.
Jun 13 2007
Georg Wrede Wrote:Jarrett Billingsley wrote:Count me in too. I've had problems with this. At least a warning would be nice."Ary Manzana" <ary esperanto.org.ar> wrote in message I don't think the compiler should rewrite it, but I don't think it should be allowed either. Either make it a warning or an error to ==/!= to null.Count me in.
Jun 13 2007
OF schrieb:Georg Wrede Wrote:definitely ! i ran into this very often and i know many D beginners who do. a warning cant hurtJarrett Billingsley wrote:Count me in too. I've had problems with this. At least a warning would be nice."Ary Manzana" <ary esperanto.org.ar> wrote in message I don't think the compiler should rewrite it, but I don't think it should be allowed either. Either make it a warning or an error to ==/!= to null.Count me in.
Jun 13 2007
Extrawurst wrote:OF schrieb:Georg Wrede Wrote:Jarrett Billingsley wrote:"Ary Manzana" wroteActually, why do we use the foo !is null idiom at all? (Or try to use the foo != null idiom?) The following works as expected: import std.stdio; void main() { Object o = new Object; // while(o !is null) while(o) { writefln("Yee."); o = null; } Object o2; while(!o2) { writefln("Haw."); o2 = new Object; } } The expected output being: Yee. Haw. Embarrassingly, I don't seem to remember if there was a historical reason for not (at some time?) using "while(o)". Anyhow, this would seem to be the canonical way to do it in a C family language in the first place. So maybe we should (of course first mark o==null as an error, and then) amend the documentation to suggest o itself as the Politically Correct test for nullness. Finally, the *error message* should suggest o itself for the test.definitely ! i ran into this very often and i know many D beginners who do. a warning cant hurtCount me in too. I've had problems with this. At least a warning would be nice.I don't think the compiler should rewrite it, but I don't think it should be allowed either. Either make it a warning or an error to ==/!= to null.Count me in.
Jun 13 2007
"Georg Wrede" <georg nospam.org> wrote in message news:467045F1.6030603 nospam.org...Actually, why do we use the foo !is null idiom at all? (Or try to use the foo != null idiom?) Anyhow, this would seem to be the canonical way to do it in a C family language in the first place. So maybe we should (of course first mark o==null as an error, and then) amend the documentation to suggest o itself as the Politically Correct test for nullness.Except there's one tiny inconsistency in the language. assert(o); This stupidly does not check that o is non-null; instead it runs the object's invariants. Which, if o really _is_ null, will cause an access violation. Whee. In this case, you have to write: assert(o !is null); Other syntaxes to run the invariant, such as "o.invariant()" or "o.assert()" have been proposed, but as usual nothing has come of it.
Jun 13 2007
Jarrett Billingsley wrote:"Georg Wrede" <georg nospam.org> wroteGeez!!! There better be a seriously solid reason for it!Actually, why do we use the foo !is null idiom at all? (Or try to use the foo != null idiom?) Anyhow, this would seem to be the canonical way to do it in a C family language in the first place. So maybe we should (of course first mark o==null as an error, and then) amend the documentation to suggest o itself as the Politically Correct test for nullness.Except there's one tiny inconsistency in the language. assert(o); This stupidly does not check that o is non-null; instead it runs the object's invariants. Which, if o really _is_ null, will cause an access violation. Whee.In this case, you have to write: assert(o !is null); Other syntaxes to run the invariant, such as "o.invariant()" or "o.assert()" have been proposed, but as usual nothing has come of it.An assert test is not the place to gratuituously save a few keystrokes! If anywhere, here clarity of expression and consistency are simply essential. If a programmer wants to assert there is an o, the first thing he'd do (unless too familiar with the above, er, interesting properties of D) is write assert(o); If a programmer wants to assert that the o object is happy and feels well, then we should have him write it explicitly. Dammit! assert(o.invariant()); or assert(o.assert()); or even assert(o.thisObjectIsHappy()); Making shortcuts (and saving keystrokes) _in the wrong place_ has historically led to grievances and wasted productivity few of us can fathom. Don't let this be another example. --- (Getting my adrenaline up here...) If there *ever* was a place where obscurity, short cuts, the unexpected, or inconsistency, are NOT welcome, it is debugging related code. For chrissake! And anybody who finds himself needing to write "assert(o&&o.assert());" five times a day, might consider putting this in F1 as an editor macro. --- After a cigarrette on the balcony, and proofreading, I got to the notion that the current behavior is trying to kill two flies in one stroke. assert(o) wants to give an access violation if o doesn't exist, and an assert failed if the object was unhappy. Well, I'm sorry but that's not good enough. As if what I've written above isn't enough, there's one more thing: testing whether we have an object at all, and testing whether it is debugging is, one step at a time. Still insist on testing both? Write two lines! Hey, _both_ your boss, and you yourself, should be able to understand the code (including the debugging statements) even after the Summer vacation.
Jun 13 2007
On Wed, 13 Jun 2007 23:32:10 +0300, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote: <snip>assert(o); This stupidly does not check that o is non-null; instead it runs the object's invariants. Which, if o really _is_ null, will cause an access violation. Whee. In this case, you have to write: assert(o !is null); Other syntaxes to run the invariant, such as "o.invariant()" or "o.assert()" have been proposed, but as usual nothing has come of it.I think this deserves its own thread, again. ;) So, I have created one: "Suggestion: "fix" assert(obj)"
Jun 14 2007
Ary Manzana wrote:Lionello Lunesu escribió:Why not have the compiler just rewrite all equality comparisons on class objects? x == y ===> (x is y || x.opEquals(y)) I mean you might as well check first that they aren't the same object, because if they are then obviously they are equal too[1]. That would make the behavior the norm and not a special case. I don't see how doing one extra pointer comparison is going to significantly affect performance. But then I guess there's that bizzarro-business about opEquals returning an int because that's "more efficient". So I guess someone is hypersensitive about object equality operations being as fast as possible. --bb [1] Unless you're trying to implement some weirdo NaN like object which is not equal to anything, including itself.That's not a bug. '==' and '!=' result in a call to opEquals, which is likely to segfault when one of the operands is null. You should use 'is' or in your case '!is'.Can't writing x == null, x != null be rewritten by the compiler to x is null, x !is null ? I think the two firsts will always segfault. When would a user want to segfault her program? Or, better asked, when would a user want to do x == null? Regards, Ary
Jun 13 2007
Bill Baxter wrote:x == y ===> (x is y || x.opEquals(y))I prefer that the compiler does not rewrite my code. There is nothing wrong with the current syntax, it's just different from what most people here are used to. If Walter changed '==' to be a reference check, then it would mean '==' works differently for different types. That inconsistency would kick up a hurricane - precisely what happened in Java. D does get this one right but a warning would be nice. Regards, Myron.
Jun 13 2007
Myron Alexander wrote:Bill Baxter wrote:But '==' *does* work differently for different types. Already. Anyway, yeh, I'd be happy with a warning (or an error really -- unless someone can think of a case where you really _want_ to crash your program like that). --bbx == y ===> (x is y || x.opEquals(y))I prefer that the compiler does not rewrite my code. There is nothing wrong with the current syntax, it's just different from what most people here are used to. If Walter changed '==' to be a reference check, then it would mean '==' works differently for different types. That inconsistency would kick up a hurricane - precisely what happened in Java. D does get this one right but a warning would be nice.
Jun 13 2007
Bill Baxter wrote:But '==' *does* work differently for different types. Already.Sorry. What I meant is that is has the same semantics. When you see ==, you can be sure that it means "check if value is the same".
Jun 14 2007
Myron Alexander skrev:Bill Baxter wrote:One could argue that = should be analogous to ==. I.e, if = assigns references, == should compare references. I am not arguing either way. :) /OskarBut '==' *does* work differently for different types. Already.Sorry. What I meant is that is has the same semantics. When you see ==, you can be sure that it means "check if value is the same".
Jun 14 2007
Oskar Linde Wrote:Myron Alexander skrev:One could also argue that the value of a class reference is the memory address of the class to which it refers, as is the case with pointers. struct A{} A* p; A* s; if (s == p) //compares address pointer 'points' at ReganBill Baxter wrote:One could argue that = should be analogous to ==. I.e, if = assigns references, == should compare references. I am not arguing either way. :)But '==' *does* work differently for different types. Already.Sorry. What I meant is that is has the same semantics. When you see ==, you can be sure that it means "check if value is the same".
Jun 14 2007
On Wed, 13 Jun 2007 10:09:24 +0300, Michael Neumann <mneumann ntecs.de> = = wrote: <snip>..., but there must be really something wrong in D (or in my =implementation), as it's at least 4x slower (and when the datasets gro=w, =it takes infinitively long time).<snip> Well, one thing that comes to mind is that allocating memory from the he= ap = is *slow* (in any programming language I guess). If you do that (i.e. heap allocation) inside a loop, a program will = probably get slower and slower, nonlinearly, when the loop count increas= es = (I recently noticed that in a (C++) project of mine). For example, if yo= u = have something like this in C++: void foo() { MyClass myclass; ... } void bar() { int i; for(i =3D 0; i < 1000000; i++) foo(); } , then you should use the 'scope' keyword in 'foo()' when programmin in = D: void foo() { scope MyClass myclass =3D new MyClass; //(or just plain "scope myc= lass = =3D new MyClass;") } This way 'myclass' is allocated from the stack instead of the heap. I hope this will help (that is, if you hadn't used 'scope' (in similar = cases), of course).
Jun 14 2007
Kristian Kilpi wrote:On Wed, 13 Jun 2007 10:09:24 +0300, Michael Neumann <mneumann ntecs.de> wrote: <snip>Thanks. Yeah, I know! That's why I'm using a free-list in my program and recycle old objects. Regards, Michael..., but there must be really something wrong in D (or in my implementation), as it's at least 4x slower (and when the datasets grow, it takes infinitively long time).<snip> Well, one thing that comes to mind is that allocating memory from the heap is *slow* (in any programming language I guess).
Jun 14 2007
Bill Baxter Wrote:Anyway, yeh, I'd be happy with a warning (or an error really -- unless someone can think of a case where you really _want_ to crash your program like that). --bbHere's one: say you have a clas Wrapper that wraps another class. You might want to overload opEquals() to test against the wrapped object reference, so opEquals(null) will return true if the wrapped object is null. For erxample, Wrapper w = new Wrapper(null); // ... if(w == null) // Doesn't segfault and does what you want it to This could be throught of as a bad design decision (of course, I think all operator overloading in general makes code harder to read, with the possible exception of Box/Variant a very few other uses), but it's a valid use case.
Jun 14 2007