在我调试我的次要移植程序时,我对类型转换差异有疑问。
这是我的来源(下方):
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 }
首先,它正常工作,现在没有错误。但我对类型铸造差异有疑问。
在第12行中,由于发生了类型转换警告,我更改了值的类型以进行调试。
但
之间有什么区别12 mac_time = localtime((const long *)&now);
和
12 mac_time = localtime(&(const long *)now);
我认为彼此之间没有区别,因为这只与'铸造价值的地址和'价值的地址铸造'不同。
但是编译器抛出后一个警告信息。
你会就这种类型的铸造问题给我一些建议吗?
答案 0 :(得分:5)
(const long *)&now
获取now
的地址,并将其解释为const long
的地址。
&(const long *)now
将now
解释为const long
的地址,并获取该地址的地址。这很危险,因为您基本上将整数或浮点数转换为指针,而没有任何理由说明为什么now
标识的内存位置可供您的应用程序访问。
答案 1 :(得分:4)
案例
mac_time = localtime((const long *)&now);
您将&now
类型的pointer to clock_t
投射到const long *
,即指向const long
类型的指针。如果localtime
期望pointer to const long
类型的参数,则没问题。而在第二种情况下
mac_time = localtime(&(const long *)now);
now
属于clock_t
,您将其投射到const long *
,然后尝试将其地址传递给函数,编译器显示错误。
现在关于错误:
error: cannot take the address of an rvalue of type 'const long *' mac_time = localtime(&(const long *)now);
你应该注意到,施法产生r-value。另一方面,&
需要l值作为操作数。这就是为什么你不能做&(const long *)now
而编译器抛出错误的原因。
最后请注意 C中没有引用来电,而是所有来电都是。
答案 2 :(得分:4)
指针强制转换完全没必要。如果你的程序看起来有效,那就太巧合了。 (我说“不走运”,因为这意味着错误未被诊断出来。)
localtime()
的参数类型为const time_t*
,不是 clock_t*
。 time_t
和clock_t
是不同的类型,用于不同的目的,即使它们可能碰巧在某些特定实现中以相同的方式定义。
将now
的定义更改为:
time_t now;
并按照以下方式致电localtime
:
mac_time = localtime(&now);
任何演员,特别是指针演员,都应该怀疑。当真正的解决方案是修复代码以便首先使用正确的类型声明事件时,强制转换通常用于使编译器警告静音。
至于你问的问题 - 嗯,这并不重要,因为代码根本不正确。这样:
mac_time = localtime((const long *)&now)
获取now
的地址(在您的代码中,类型为clock_t*
),并将其转换为const long*
。由于localtime
期望类型为const time_t*
的参数,并且显然 time_t
在您的实现中定义为long
,因此出现他们工作。
此:
mac_time = localtime(&(const long *)now);
获取now
的值(此时尚未初始化)并将其转换为const long*
;换句话说,它采用垃圾数值并将其转换为指针。然后它尝试获取该指针的地址 - 但由于它是指针值,而不是指针对象,因此它没有地址。以上是编译时错误。 (我希望您的编译器将此视为致命错误,而不仅仅是警告。)
但是忘了这一切。只需首先声明您的对象是正确的类型,您就不必担心强制转换。
(有些情况下,演员阵容,甚至指针演员阵容都是必要且恰当的,但不适合你在这里尝试做的事情。)