6

I am confused about a function dictCreate() in file dict.c of redis implementation. I am going to paste the code here:

/* Create a new hash table 
 * T = O(1)
 */
dict *dictCreate(dictType *type, void *privDataPtr) {
    dict *d = zmalloc(sizeof(*d));
    _dictInit(d, type, privDataPtr);
    return d;
}

variable d is used in zmalloc(sizeof(*d)), but theoretically it will exist when this line was executed. So my question is how it is possible to use variable d before it is declared?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
ssj
  • 1,737
  • 2
  • 16
  • 28
  • `d` is already declared :P. you can see that if you rewrite the declaration to `dict* d` which means the same. – John Odom Aug 05 '15 at 15:09
  • 2
    It is using its type, not the value. The type is known in the compile time, so no problem here. – Eugene Sh. Aug 05 '15 at 15:09
  • Very close to [Is dereferencing null pointer valid in sizeof operation](http://stackoverflow.com/q/19785518/1708801). – Shafik Yaghmour Aug 05 '15 at 15:11
  • BTW, since it is probably does not deserve a question by itself.. What would be preferable way here, `sizeof(*d)` or `sizeof(dict)` and why? – Eugene Sh. Aug 05 '15 at 15:12
  • 1
    @EugeneSh. I don't see any problem with `sizeof(*d)` – Sourav Ghosh Aug 05 '15 at 15:13
  • @SouravGhosh No problem at all. I am asking what is better :) – Eugene Sh. Aug 05 '15 at 15:14
  • 1
    @EugeneSh.; Its matter of choice. Use either. – haccks Aug 05 '15 at 15:14
  • 2
    @EugeneSh. [Note-to-self : not to get fancy with non-native language :-)] I tried to mean, here also, `sizeof(*d)` is valid, so I'll go with it. Anyway, it is the preferred way by _most_ (note, I did not say _all_). :-) – Sourav Ghosh Aug 05 '15 at 15:18
  • 1
    @EugeneSh.: I agree with Sourav. `*d` will use the type of the pointer's target, regardless of later change. Not very relevant here, but if you have some lines between the pointer definition and the `malloc`, it might save time thinking which type it has (just put `*` before the name) and avoids errors if you change its type for some reason. – too honest for this site Aug 05 '15 at 15:36
  • When I read the question I was wondering *Why not use `sizeof(dict)`* thanks for answering. – robbmj Aug 05 '15 at 17:31

3 Answers3

7

sizeof is not a function, it is an operator. It is executed (evaluated, to be exact) at compile time, so the scope or lifetime you're thinking about d, does not apply here. All it needs to know is the type of *d and that is known at compile time. Sufficient.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • so I know that `sizeof` will execute at compile time, and I want to know something more about the `operator` that will be executed in compile time. thx! – ssj Aug 05 '15 at 15:14
  • @whatout: Could you elaborate? "I know that sizeof will execute at compile time ..." contradicts "I want to know something more about the operator ..." actually. Either you know the _operator_ `sizeof`, or you need to know more about it. I presume you know what `sizeof` actually does, as you use it already. – too honest for this site Aug 05 '15 at 15:43
  • @Olaf I want to know if that are other operator that will execute at compile time? – ssj Aug 06 '15 at 01:11
  • @whatout: Almost any if its operands can be evaluated at compile-time. However, you should read a good C book. Please understand SO is no tutorial or discussion site. – too honest for this site Aug 06 '15 at 01:58
1

The statement

dict *d = zmalloc(sizeof(*d));  

is equivalent to

dict *d;
d = zmalloc(sizeof(*d));  

So, dict *d declares d as a pointer to dict type and = zmalloc(sizeof(*d)); used for initialization. dict *d = zmalloc(sizeof(*d)); declares d as dict * and then initializes it in single line.

haccks
  • 104,019
  • 25
  • 176
  • 264
1

Your assumption is wrong, the object exists starting from the = sign that starts the initialization. E.g in a initializer you are well allowed to use the address of the object that you are initializing.

Here, in addition, no access to the object itself is needed, sizeof only uses the type in this case.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177