Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call by reference value's type casting in Unix

While I debug my minor porting program, I have question about type casting differences.

Here is my source (below) :

  1 #include <time.h>
  2 #include <stdio.h>
  3 
  7 int main () {
  8     clock_t now; //unsigned long 
  9     struct tm * mac_time; // const long
 10     char *time_str;
 11     now = time (NULL);
 12     mac_time = localtime((const long *)&now); 
 13                           // localtime ( const long <- unsigned long)
 13     time_str = asctime(mac_time);
 14     printf("Now : %s\n",time_str);
 15     return 0;
 16 }

First, it works properly, there's no error right now. But I have a question about type casting difference.

In line 12, since type casting warning has occurred, I changed the value's type for debug.

but what is the difference between

12     mac_time = localtime((const long *)&now);

and

12     mac_time = localtime(&(const long *)now);

I thought there's no difference to each other, because this is only different from 'casted value's address and 'value's address casted'.

But complier throws out warning message latter one.

Will you give me some advice for this type casting issue?

like image 363
sogo Avatar asked Dec 11 '22 08:12

sogo


2 Answers

(const long *)&now takes the address of now and interprets it as an address of a const long.

&(const long *)now interprets now as an address of a const long and takes the address of that address. This is dangerous, because you are basically converting an integer or float to a pointer without any justification as to why the memory location identified by now is accessible to your application.

like image 169
Oswald Avatar answered Dec 14 '22 23:12

Oswald


For the case

mac_time = localtime((const long *)&now);  

you are casting &now, which is of pointer to clock_t type, to const long *, i.e, pointer to const long type. No problem if localtime expecting argument of type pointer to const long type. While in second case

 mac_time = localtime(&(const long *)now);  

now is of clock_t and you are casting it to const long * and then trying to pass its address to the function and the compiler is showing you error.
Now about the error:

error: cannot take the address of an rvalue of type 'const long *' mac_time = localtime(&(const long *)now); 

You should note that casting produce an r-value. On the other hand & require an l-value as an operand. That's why you can't do &(const long *)now and compiler is throwing the error.

And finally note that there is no call by reference in C instead all calls are by value.

like image 41
haccks Avatar answered Dec 15 '22 01:12

haccks