fel*_*eek 18 c pointers casting
请考虑以下小示例代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *i;
char *c1, *c2;
i = malloc(4);
*i = 65535;
c1 = i;
c2 = (char *)i;
printf("%p %p %p\n", i, c1, c2);
printf("%d %d", *c1, *c2);
free(i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我分配内存来存储一个指向的整数i.然后,我存储值65535(1111 1111 1111 1111)*i.我接下来要做的是让两个char*指针也指向整数.我做了两次,但是用两种不同的方式:c1 = i;和c2 = (char *)i;.最后,我在屏幕上打印所有指针和所有值.这三个指针指向同一个地址,这两个值*c1和*c2正确(-1) .
但是,编译器会在此行中生成警告:c1 = i;.生成警告是因为我没有使用(char *)强制转换进行分配.
我想问的是为什么编译器会生成此警告,因为我没有看到使用中的任何差异c1 = i ; 或c2 = (char *)i;.在这两种情况下,结果都是具有相同大小(以字节为单位)的相同地址.这是适用于所有类型转换,哪怕是一个(int *)演员,(float *)演员,(short *)演员表等他们都产生相同的值,但是编译器将只接受它没有一个警告,如果正在使用的演员阵容指针的类型.
我真的想知道为什么编译器要求该转换,即使结果总是相同的.
R S*_*ahu 33
当你使用:
c2 = i;
Run Code Online (Sandbox Code Playgroud)
编译器警告你int*要将类型赋值给char*.这可能是一个无意的错误.编译器警告你,如果它确实是一个无意的错误,你有机会修复它.
当你使用:
c2 = (char *)i;
Run Code Online (Sandbox Code Playgroud)
你告诉编译器你作为程序员知道你在做什么.
eca*_*mur 17
你的程序无效; 除非使用强制转换,否则当指向的类型是不兼容的类型时,不允许在指针类型之间进行赋值.
6.5.4施法者
3 - 除了6.5.16.1的约束允许之外,涉及指针的转换应通过显式转换来指定.
编译器接受您的代码作为扩展,但另一个编译器可能拒绝您的代码,这样做是正确的.这就是编译器在省略强制转换时发出警告的原因.
指向不同类型对象的指针可能在各自的大小和对齐方面有所不同:
§6.2.5/ 26类型
指向void的指针应具有与指向字符类型的指针相同的表示和对齐要求.同样,指向兼容类型的限定或非限定版本的指针应具有相同的表示和对齐要求.所有指向结构类型的指针都应具有相同的表示和对齐要求.所有指向union类型的指针都应具有相同的表示和对齐要求.指向其他类型的指针不需要具有相同的表示或对齐要求.
特别是,sizeof(char *)可能有不同的价值sizeof(int *).此外,char *可能有不同的对齐要求int *.因此,隐式演员会产生警告.这就是C标准包含以下准则的原因:
§6.5.4/ 1
除了6.5.16.1的约束允许之外,涉及指针的转换应通过显式转换来指定.