anu*_*g86 4 c++ network-programming
我遇到了一个套接字编程教程,其中引用了它
“指向结构sockaddr_in的指针可以转换为指向结构sockaddr的指针,反之亦然 ”
我不明白如何将sockaddr_in强制转换为sockaddr。将Big类型的指针转换为Small类型的指针应具有UD行为。
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
struct sockaddr_in {
short int sin_family; // Address family, AF_INET
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr
};
Run Code Online (Sandbox Code Playgroud)
如何不能强制转换?将它们相互投射是不安全的吗?
如果我有一个A类只有两个整数,而B类则只有4个整数。如果我有一个类型为B的指针并将其强制转换为类型A,那么请确保我可以获取前两个元素。但是,如果类A具有首先声明的2个字符和之后声明的2个整数,则指针将无法正确获取值,因为在这种情况下,对象布局将有所不同。
编辑1:
class Anu
{
public:
char a;
int b;
Anu()
{
a='a';
}
};
class Anurag
{
public:
Anurag() { a=4;}
int a;
int b;
int c;
int d;
};
int main()
{
Anu objanu;
Anurag objanurag;
Anurag *ptrAnurag= &objanurag;
ptrAnurag= (Anurag*)&objanu;
cout<<ptrAnurag->a; //Some weird value here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
假设我更改示例,以便通过调整变量类型使两个类具有相同的大小...即使大小保持不变,对象布局仍可能不同。
我将在@gsamaras答案中添加“未定义行为”并不总是意味着坏事将要发生的说法。未定义行为实际上说:“我们不提供有关XYZ发生时下一步将如何发生的任何规范”。
(* C ++标准)。
这是进行操作系统的地方,说“它是我们定义的”。
虽然铸造结构无关(sockaddr_in,sockaddr)可以是由标准定义的操作中,OS API指定它是与他们的API有效。
它们的大小相同,所以不,您不会得到任何UB!
\n证明:
\n#include <stdio.h>\n\nstruct sockaddr {\n unsigned short sa_family; // address family, AF_xxx\n char sa_data[14]; // 14 bytes of protocol address\n};\n\n// src: http://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html\nstruct in_addr {\n unsigned long s_addr; // load with inet_aton()\n};\n\nstruct sockaddr_in {\n short int sin_family; // Address family, AF_INET\n unsigned short int sin_port; // Port number\n struct in_addr sin_addr; // Internet address\n unsigned char sin_zero[8]; // Same size as struct sockaddr\n};\n\nint main (void) {\n printf("%zu\\n", sizeof(unsigned short) + sizeof(char) * 14);\n printf("%zu\\n", sizeof(short int) + sizeof(unsigned short int) + sizeof(struct in_addr) + sizeof(unsigned char) * 8);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n输出:
\n16\n16\nRun Code Online (Sandbox Code Playgroud)\n很好的评论: sockaddr: 2+14=16, sockaddr_in:2+2+4+8=16 \xe2\x80\x93 Amer Agovic
\n您可能还想看看这个问题:Why isn't sizeof for a struct equal to the sum of sizeof of every member?
\n请检查这个问题:Is it possible tocast struct to another?
\n我也在这里复制Benoit的答案:
\n\n\n这称为类型双关语。这里,两个结构体具有相同的大小,因此不存在结构体大小的问题。尽管您几乎可以将任何内容转换为任何内容,但使用结构进行转换很容易出错。
\n
还有理查德·罗斯三世 (Richard J. Ross III) 的这一篇:
\n\n\n这是 C 的“继承”形式(注意引号)。这是可行的,因为 C 不关心地址中的基础数据,只关心您将其表示为什么。
\n该函数通过使用 sa_family 字段来确定它实际上是什么结构,并将其转换为函数内正确的 sockaddr_in 。
\n