struct vs class for a simple token in my d lexer

Dmitry Olshansky dmitry.olsh at gmail.com
Mon May 14 10:37:01 PDT 2012


On 14.05.2012 21:33, Dmitry Olshansky wrote:
> On 14.05.2012 21:20, Roman D. Boiko wrote:
>> On Monday, 14 May 2012 at 16:41:39 UTC, Jonathan M Davis wrote:
>>> On Monday, May 14, 2012 17:10:23 Roman D. Boiko wrote:
>>>> (Subj.) I'm in doubt which to choose for my case, but this is a
>>>> generic question.
>>>>
>>>> http://forum.dlang.org/post/odcrgqxoldrktdtarskf@forum.dlang.org
>>>>
>>>> Cross-posting here. I would appreciate any feedback. (Whether to
>>>> reply in this or that thread is up to you.) Thanks
>>>
>>> For the question in general, there are primarily 2 questions to
>>> consider:
>>>
>>> 1. Do you need inheritance/polymorphism?
>>> don't have inheritance.
>>>
>>> 2. Do you need a value type or a reference type?
>>>
>>> If you need inheritance/polymorphism, you have to use classes, because
>>> structs
>>>
>>> If you want a value type, you have to use structs, because classes are
>>> reference types.
>>>
>>> If you want a reference type, then you can use either a class or a
>>> struct, but
>>> it's easier with classes, because classes are always reference types,
>>> whereas
>>> structs are naturally value types, so it can take more work to make them
>>> reference types depending on what its member variables are.
>>>
>>> One other thing to consider is deterministic destruction. The only way
>>> to get
>>> deterministic destruction is to have a struct on the stack. Value
>>> types will
>>> naturally get that, but if you want a reference type with determinstic
>>> destruction, then you're probably going to have to use a ref-counted
>>> struct.
>>>
>>> In the vast majority of cases, that should be enough to decide whether
>>> you
>>> need a class or a struct. The main case that it doesn't is the case
>>> where you
>>> want a reference type and don't necessarily want a class, and that
>>> decision
>>> can get complicated.
>>>
>>> In the case of a token in a lexer, I would definitely expect that to
>>> be a value
>>> type, which means using a struct.
>>>
>>> - Jonathan M Davis
>> Semantics is clearly of value type. But it would be nice to
>> minimize size of instance to be copied. (I could simply split it
>> into two, if some part is not used in most scenarios.)
>>
>> Just curious: how to implement a struct as ref type? I could add
>> indirection (but then why not just use a class?), or simply pass
>> by ref into all methods. Are there any other options?
>>
>
> Use the damn pointer ;)
>
> In a few words (lines) overwrite struct contents (first 4-8 bytes) with
> pointer to next free token:
>
> //setup:
> void get_some_memory()
> {
> Token pool = new Token[block_size];
> for(size_t i=0;i<pool.length-1; i++)
> *(void**)(tok.ptr+i) = tok.ptr+i+1;
> *(void**)&tok[$-1] = null; //end of list
> }
> Token* head = pool.ptr;//this guy in TLS
>
> //usage:
> Token* new_tok(){
	if(!head)
		get_some_memory();
	Token* r = head;
	head = *(token**)head;
	return r;
> }

Not so trustworthy :o)
But hopefully you get the idea. See something simillar in std.regex, 
though pointer in there also serves for intrusive linked-list.

>
> void free_tok(Token* tok){
> *(void**)tok = head;
> head = tok;
> }
>
> Untested but trustworthy ;)
>
>> Thanks to everybody for your feedback, it looks like I'll stay
>> with struct.
>
>


-- 
Dmitry Olshansky


More information about the Digitalmars-d-learn mailing list