简体   繁体   English

如何在使用pedantic标志进行编译时,在没有得到任何警告的情况下,在C ++中从(void *)重新键入int?

[英]How to retype from (void *) to int in C++ without getting any warning when compiling with pedantic flag?

I have mutlithread client-server application that communicates via sockets . 我有通过sockets通信的mutlithread客户端-服务器应用程序。 I create new thread with this construction: 我用这种构造创建新线程:

 pthread_t thread;
 pthread_create(&thread, NULL, c->sendMessage, (void *) fd);

where fd is a ID of the connection and c->sendMessage is a function, that is called after a new thread is created and that handles this thread. 其中fd是连接的ID, c->sendMessage是一个函数,在创建新线程并处理该线程之后调用该函数。 Within this function I need to send some message via send(int sockfd, const void *buf, size_t len, int flags); 在此函数中,我需要通过send(int sockfd, const void *buf, size_t len, int flags);发送一些消息send(int sockfd, const void *buf, size_t len, int flags);

so I get sockfd this way: 所以我这样得到sockfd

void * Client::sendMessage(void *threadid) {
   int sockfd = (int) threadid;
   // some more code here and in the end I send the data via send(int sockfd, const void *buf, size_t len, int flags)
}

I compile with -pedantic flag and most of the compilers (mine including) don't throw any warning or error during the compilation. 我使用-pedantic标志进行编译,大多数编译器(包括我的编译器)在编译过程中都不会引发任何警告或错误。 But some throw an error during compilation saying that this retyping from void * to int is unsafe and can cause loose of precision . 但是有些人在编译时抛出错误,说从void *int这种重新输入是不安全的,并且可能导致loose of precision I understand, that this is not a good solution and it should be done cleaner. 我了解,这不是一个好的解决方案,应该做得更干净。 But I can't find out how. 但我不知道如何。 Could anybody advice me any clean practice, how to retype ponter to int and avoid any warning during compilation? 有人可以建议我采取任何干净的做法吗,如何将ponter重新输入为int并避免在编译过程中出现任何警告?

What is problem to send pointer, instead of integer? 发送指针而不是整数有什么问题? Convert int to void* , or void* to int , it's not standard conformant solution. 转换intvoid* ,或void*int ,它不是标准的符合性解决方案。

pthread_create(&thread, NULL, c->sendMessage, new int(fd));

int* sockfd_ptr = (int*)threadid;
// some usage
delete sockfd_ptr;

Any pointer is convertible to void* , so it should works well. 任何指针都可以转换为void* ,因此应该可以正常工作。 Don't forget to delete threadid in some place of your program. 不要忘记在程序的某些位置删除threadid May be it will better to create some class, where store reference/pointer. 创建存储引用/指针的类可能会更好。

Also, I can't understand, how you send member function into C function, it's not correct too. 另外,我不明白如何将成员函数发送到C函数中,这也不正确。

It's an extremely bad idea to cast from int to void* and then back to int because there are absolutely no guarantees in the C++ standard that those two types are the same size. intvoid* ,然后再转换为int是一个非常糟糕的主意,因为C ++标准中绝对不能保证这两种类型的大小相同。

If you really must cast between an integer type and a pointer (which is not a very good idea, but sometimes there is no other choice), use intptr_t or uintptr_t instead of int since they are guaranteed to be the same size as a pointer. 如果确实必须在整数类型和指针之间进行uintptr_t (这不是一个好主意,但有时别无选择),请使用intptr_tuintptr_t而不是int因为可以保证它们的大小与指针相同。 This way you won't get any warning. 这样,您将不会收到任何警告。

As a side note, legacy C casts like you're doing are frowned upon in C++ because you can't be sure what they are doing under the hood (it could be a static_cast or a reinterpret_cast , who knows?). 顺便提一句,由于您无法确定它们在static_cast正在做什么(可能是static_castreinterpret_cast ,谁知道?),因此像C ++这样的传统C转换在C ++中就被皱眉了。 Prefer using proper C++ casts, namely reinterpret_cast in your case. 最好使用适当的C ++强制转换,在您的情况下为reinterpret_cast

您可以添加诸如static_assert(sizeof(fd) <= sizeof(void*), "problem") ,并依赖于您的实现文档,reinterpret_cast将在这种情况下往返。

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

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