我正在编写一个套接字程序,我将
struct sockaddr_in
误输入为 struct sockaddrr_in
(注意额外的 r
),但我没有收到任何编译器错误,只有 incompatible-pointer-types
警告。
这里有一个最小的可重现程序来演示这个问题。
#include <stdio.h>
struct Addr {
int flat_no;
};
struct Person {
struct Addr *address;
};
int main()
{
struct Person p;
struct Addr addr;
p.address = &addr;
struct Person *ptr = &p;
struct Addr *a = (struct Addrr *)ptr->address; // struct Addr mistyped as Addrr
printf("no error!!");
}
gcc
和 clang
都会产生此警告:
<source>:20:22: warning: initialization of 'struct Addr *' from incompatible pointer type 'struct Addrr *' [-Wincompatible-pointer-types]
20 | struct Addr *a = (struct Addrr *)ptr->address;
| ^
由于
struct Addrr
从未在程序中定义,编译器如何能够解析错误键入的符号?将 ptr->address
类型转换为未定义的类型 struct Addrr
有什么影响?
因为cast是第一次出现
struct Addrr
,所以起到了声明那个类型的作用。该类型不完整,因为它没有定义,但您仍然可以创建指向不完整类型的指针。
所以当你收到关于在不兼容的指针类型之间转换的警告时,你不会收到关于其他类型的错误。
cast操作符定义如下
cast-expression:
unary-expression
( type-name ) cast-expression
struct Addrr *
是指针类型。指针类型始终是完整类型。虽然尖型struct Addrr
是不完整的类型。