问题描述
说我有一个名为socket
的Windows套接字。如果socket
传递给未写入的函数。例如说一个函数,它向客户端发送简单的消息/字节,例如Hello you're connected to the server!
。
例如:
void send_hello(SOCKET socket,char* data) {
send(socket,data,sizeof(data),0);
}
将套接字作为const
传递是否安全?例如:
void send_hello(const SOCKET socket,0);
}
我脑子里有些东西告诉我,我应该将socket
传递为const
,而不是将其传递为可写内存。我知道套接字是文件描述符,所以显然我对套接字的工作方式以及它们是否始终被写入感到困惑。但是,当将socket
作为const
传递时,我的代码有效。
我的总体问题是:
可以将对象类型为SOCKET
的变量作为const
传递吗?还是应该说SOCKET
始终在可写内存中,而不管作用域如何?
解决方法
将顶级const
添加到函数参数始终是安全的。这甚至不是函数签名的一部分,它只是告诉编译器在函数体内,您不会将参数更改为其他值。这样一来,编译器就可以在您重新分配参数的地方发现错误。
请注意,当您调用send
时,第一个参数正在接收参数copy
的{{1}}(也称为“按值传递”)。因此,socket
是否在可写内存中没有区别。
VirtualLock()
只是一个整数(具体地说,SOCKET
是SOCKET
的别名,即指针大小的无符号整数),因此在您的示例中这并不重要如果您将其传递为UINT_PTR
,则为按值传递 。 const
采用非常量值send()
,因此无论什么情况,您的SOCKET
都将按值进行复制。
如果愿意,可以通过SOCKET
传递socket
参数,这仅意味着您的函数无法为const
参数分配新值。与socket
所引用的基础套接字资源无关。