Sam*_*Sam 15 c pointers casting
我想知道是否存在以下区别:
我还想知道是否有充分的理由使用(2)超过(1).我在遗留代码中看到过(2)这就是我想知道的原因.从上下文来看,我无法理解为什么(2)被优先于(1).从我写的下面的测试中,我得出的结论是,至少上传的行为在两种情况下都是相同的:
/* compile with gcc -lm */
#include <stdio.h>
#include <math.h>
int main(void)
{
unsigned max_unsigned = pow(2, 8 * sizeof(unsigned)) - 1;
printf("VALUES:\n");
printf("%u\n", max_unsigned + 1);
printf("%lu\n", (unsigned long)max_unsigned + 1); /* case 1 */
printf("%lu\n", *((unsigned long *)&max_unsigned) + 1); /* case 2 */
printf("SIZES:\n");
printf("%d\n", sizeof(max_unsigned));
printf("%d\n", sizeof((unsigned long)max_unsigned)); /* case 1 */
printf("%d\n", sizeof(*((unsigned long *)&max_unsigned))); /* case 2 */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
VALUES:
0
4294967296
4294967296
SIZES:
4
8
8
Run Code Online (Sandbox Code Playgroud)
从我的角度来看,(1)和(2)之间应该没有区别,但我想咨询SO专家进行健全性检查.
第一次演员是合法的; 第二个演员可能不合法.
第一个演员告诉编译器使用变量类型的知识来转换为所需的类型; 只要在语言标准中定义了正确的转换,编译器就会这样做.
第二个演员告诉编译器忘记它对变量类型的了解,并将其内部表示重新解释为不同类型*的内部表示.这具有有限的适用性:只要二进制表示与目标指针指向的类型匹配,该转换就可以工作.但是,这不等同于第一次投射,因为在这种情况下,价值转换永远不会发生.
将正在转换的变量的类型切换为具有不同表示的变量(例如a)float,可以很好地说明这一点:第一次转换产生正确的结果,而第二次转换产生垃圾:
float test = 123456.0f;
printf("VALUES:\n");
printf("%f\n", test + 1);
printf("%lu\n", (unsigned long)test + 1);
printf("%lu\n", *((unsigned long *)&test) + 1); // Undefined behavior
Run Code Online (Sandbox Code Playgroud)
这打印
123457.000000
123457
1206984705
Run Code Online (Sandbox Code Playgroud)
struct/时union第一个成员是有效的转换源/目标.否则,这会导致未定义的行为.有关完整说明,请参阅C 2011(N1570),6.5 7.谢谢Eric Postpischil指出定义第二次转换的情况.