about pointer syntax

spir denis.spir at gmail.com
Thu Oct 14 15:54:56 PDT 2010


On Thu, 14 Oct 2010 17:16:23 -0400
bearophile <bearophileHUGS at lycos.com> wrote:

> spir:
> 
> > As a way to start learning D by practicing, I'm trying to implement a symbol table as linked list: see prototype code of the structs below. (Hints about good D coding welcome :-)
> 
> I have modified your code a little:
> 
> struct Symbol {
>     string name;
>     int element;
>     Symbol* next;
> 
>     this(string n, int e, Symbol* s=null) {
>         name = n;
>         element = e;
>         next = s;
>     }
> }
> 
> struct List {
>     Symbol* first;
> 
>     int element(string name) {
>         for (auto symbol = this.first; symbol != null; symbol = symbol.next)
>             if (symbol.name == name)
>                 return symbol.element;
>         return 0;
>     }
> }
> 
> void main() {
>     auto l = List(new Symbol("baz", 3, new Symbol("bar", 2, new Symbol("foo", 1))));
>     assert(l.element("bar") == 2);
> }

Thank you very much! That's exactly what I need to learn good practice, even more with comments below. (Hope you don't mind if I send other bits of code to be improved that way?)

> - There's no need to initialize int to 0, string to "", pointers to null, etc, the compiler does it for you on default. Each type has a default init value (for floating point values it uses a NaN).

Right. I think at keeping explicit defaults like "int element = 0" for documentation. It means "that's precisely what I want as default value", as opposed to just the language's "init". (So, for Symbol fields, I would only write element & next defaults explicitely, since name has no meaningful default: it must be provided.)

> - Generally don't put a space before the ending semicolon.
> - Four spaces indent and no space before the "*" of the pointer, as you have done, is OK.
> - It's generally better to put one or two blank lines before structs, functions, etc

(About ';', I like to separate actual code from grammatical separators, which are just noise to my eyes. If I ever write a lib for public use, I'll follow such styling guidelines ;-)

> - Using a while loop as you have done is OK, I have used a for loop just to show a shorter alternative.

Thanks, as I said I'm not used to PLs of the C family. Wouldn't have ever thought that the "stepping" statement of a for loop can be something else as incrementation.

> - (*symbol).name is written symbol.name in D.

Very good.

> - After an { generally a \n is used, there's no need to use the ; after the }

Right.

> - using 0 as error return value is sometimes OK, but also keep in mind that exceptions are present.

;-) Was just a placeholder before I decide how to cope with "finding failure".

> - while(symbol) is acceptable, but some people prefer to put an explicit comparison to make the code more readable.

Right, guess you mean while(symbol != null)?

> - sometimes using "auto" helps.

I need to explore this further (what's the actual purpose of "auto").

> - In D linked lists are doable, but much less used, think about using a dynamic array, or even in this case an associative array:
>
> void main() {
>     auto aa = ["foo": 1, "bar": 2, "baz": 3];
>     assert(aa["bar"] == 2);
> }

Yes, it was just an exercise. For curiosity, I intend to benchmark lists vs sequential arrays vs associative arrays, for various element counts.
(Did that already in another language (freepascal), to know what kind of data structures were suited for symbol tables representing the content of record-like objects, which number of entries is typically small since hand-written by the programmer: sophisticated structures like associative arrays and tries started to perform better than plain sequences for counts >> 100.)

> > 1. To please the compiler, I had to wrap dereferencing in parens, like in "(*symbol).name". Is this just normal (for disambiguation)?
> > 2. Just noticed the compiler accepts "symbol.name", while symbol is a pointer: is there implicit dereferencing of pointers to structs? If yes, does this also apply to pointers to arrays (for information, this what Oberon does).
> 
> Generally the field dereferencing doesn't require the "(*symbol).name", in D you use "symbol.name".
> Pointers to arrays are possible, but quite uncommon in D.

Sure, there are builtin dynamic arrays :-)
I'll check whether manually pointed arrays also silently dereferencing (on element access, on attribute access)?

> > And a note: had forgotten to add an empty main(), just for compiling: the linker produced a rather big amount of error text without any hint to the actual issue. Maybe dmd could cope with that before calling gcc?
> 
> I agree, I have bug report 4680 open on something similar:
> http://d.puremagic.com/issues/show_bug.cgi?id=4680

Good.

> > Finally: the reference is rather harsh for me, esp there are very few example (I have few practice of C, and none of C++); the bits of tutorials I found are too light or just started (toc points to empty pages). Is there anywhere online a kind of D programming guide, even not polished or possibly unfinished (I know about the book; maybe I'll order it, but in meantime...).
> 
> The D2 documentation isn't abundant yet :-)

I'll do what I can on one of the already started wikibooks about D if I find energy for that...

> Bye,
> bearophile

Thanks again,
Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com



More information about the Digitalmars-d-learn mailing list