简体   繁体   English

为什么引用的int被强制转换为void指针?

[英]Why is the referenced int being cast to a void pointer?

void Link::keepalive(bool enable){
    int opt = enable? 1 : 0;
    ::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt));
}

I keep seeing code like the following in some of the more low-level c functions especially when it pertains to sockets and networking operations. 我继续在一些更低级别的c函数中看到如下代码,特别是当它涉及套接字和网络操作时。

I'm coming from a python background, and I've certain looked around for good explanations as to what (void *)&opt is doing, but have yet to find a good explaination. 我来自一个python背景,我肯定四处寻找关于什么(void *)&opt正在做的很好的解释,但还没有找到一个很好的解释。

I get that a reference is merely a pointer with restrictions. 我知道引用只是一个有限制的指针。

The signature for setsockopt setsockopt的签名

int setsockopt(int socket, int level, int option_name,
   const void *option_value, socklen_t option_len);  

Its second last argument should be of type void * . 它的第二个参数应该是void *类型。 To make &opt of type void * it is catsted to that type. &opt类型为void *它会被设置为该类型。

Also note that &opt is the address of opt object. 另请注意, &optopt对象的地址。 Its not reference. 它不是参考。

It is indeed quite a mess which exists in the first place because setsockopt() is supporting tons of different options (SO_KEEPALIVE is just one of them). 它确实存在于第一位,因为setsockopt()支持大量不同的选项(SO_KEEPALIVE只是其中之一)。

  • To enable passing any parameter (including future extensions), they've said that setsockopt() will accept a pointer to the parameter, where parameter type is any pointer (and is implicitly defined by option_name parameter, in this case SO_KEEPALIVE). 为了启用传递任何参数(包括将来的扩展),他们说setsockopt()将接受指向参数的指针,其中参数类型是任何指针 (并且由option_name参数隐式定义,在本例中为SO_KEEPALIVE)。

    • this ensures that setsockopt() prototype remains the same for all the future values of SO_* options 这确保了对于SO_ *选项的所有未来值,setsockopt()原型保持不变
  • in C, "any pointer" is written as "void*" 在C中,“任何指针”写为“void *”

  • &opt is "pointer to opt" (or "address of opt") &opt是“指向选择”(或“选择地址”)

  • as "opt" has type int, "&opt" has type int*, so to convert it to void*, there is an "explicit cast" (void*)&opt in your code 由于“opt”的类型为int,“&opt”的类型为int *,因此要将其转换为void *,代码中会有“显式强制转换”(void *)&opt

    • however, in most cases it is not necessary, as cast to void* is implicit, so simple "&opt" should do 但是,在大多数情况下,没有必要,因为转换为void *是隐含的,所以简单的“&opt”应该这样做
  • this kind of trickery, while common in C APIs, is generally discouraged in C++, so don't take it as an example of "how to write C++ programs" 这种技巧虽然在C API中很常见,但在C ++中通常是不鼓励的,所以不要把它作为“如何编写C ++程序”的例子。

Take a look at MSDN's documentation for the setsockopt function, in particular the Remarks section: 查看MSDN的setsockopt函数文档,特别是备注部分:

There are two types of socket options: Boolean options that enable or disable a feature or behavior, and options that require an integer value or structure. 套接字选项有两种类型:启用或禁用功能或行为的布尔选项,以及需要整数值或结构的选项。 To enable a Boolean option, the optval parameter points to a nonzero integer. 要启用布尔选项,optval参数指向非零整数。 To disable the option optval points to an integer equal to zero. 要禁用选项optval指向等于零的整数。 The optlen parameter should be equal to sizeof(int) for Boolean options. 对于布尔选项,optlen参数应等于sizeof(int)。 For other options, optval points to an integer or structure that contains the desired value for the option, and optlen is the length of the integer or structure. 对于其他选项,optval指向包含选项所需值的整数或结构,optlen是整数或结构的长度。

It is a common practice in C APIs to pass function arguments that can be of different type/length as the most general pointer type (void *) pointing on their address in memory. 在C API中,通常的做法是传递函数参数,这些函数参数可以是与指向内存中地址的最常规指针类型(void *)不同的类型/长度。

&opt returns pointer/address to opt of type (int *) in your case, so it needs to be cast to (void *) . &opt返回指针/地址以在您的情况下opt类型(int *) ,因此需要将其强制转换为(void *) Also when writing for C++, prefer using explicit type conversions . 另外,在为C ++编写时,更喜欢使用显式类型转换

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM