使用 pedantic flag 编译时,如何在 C++ 中从 (void *) 重新输入到 int 而不会收到任何警告?
Posted
技术标签:
【中文标题】使用 pedantic flag 编译时,如何在 C++ 中从 (void *) 重新输入到 int 而不会收到任何警告?【英文标题】:How to retype from (void *) to int in C++ without getting any warning when compiling with pedantic flag? 【发布时间】:2013-06-07 11:39:58 【问题描述】:我有通过sockets
通信的mutlithread
客户端-服务器应用程序。
我用这种结构创建了新线程:
pthread_t thread;
pthread_create(&thread, NULL, c->sendMessage, (void *) fd);
其中fd
是连接的ID,c->sendMessage
是一个函数,在创建新线程后调用并处理该线程。在这个函数中,我需要通过send(int sockfd, const void *buf, size_t len, int flags);
发送一些消息
所以我这样得到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)
我使用-pedantic
标志进行编译,并且大多数编译器(包括我的)在编译期间不会抛出任何警告或错误。但是有些人在编译过程中抛出一个错误,说从void *
到int
的重新输入是不安全的,可能会导致loose of precision
。我明白,这不是一个好的解决方案,应该做得更干净。但我不知道怎么做。任何人都可以建议我任何干净的做法,如何将 ponter 重新输入为 int 并在编译期间避免任何警告?
【问题讨论】:
如果你此时使用std::thread
,这个问题似乎是可以避免的。
是的,这可能是解决方案,如何避免这个问题,但问题不是,如何避免,而是如何解决它:)
【参考方案1】:
发送指针而不是整数有什么问题?将int
转换为void*
,或将void*
转换为int
,这不是标准的符合解决方案。
pthread_create(&thread, NULL, c->sendMessage, new int(fd));
int* sockfd_ptr = (int*)threadid;
// some usage
delete sockfd_ptr;
任何指针都可以转换为void*
,所以它应该可以正常工作。不要忘记在程序的某个位置删除threadid
。
可能最好创建一些存储引用/指针的类。
另外,我不明白,你如何将成员函数发送到 C 函数中,这也不正确。
【讨论】:
因为我需要在vectors
和maps
中保存线程ID 才能进一步使用它们,所以这不仅仅是发送消息。是的,将pointers
保存在vector
中也可能有效,但我也很好奇如何解决这个问题,以及为什么有些编译器对此没有任何问题,而有些则有。
new int(fd)
很好,但有人需要delete
。【参考方案2】:
从int
转换为void*
然后再转换回int
是一个非常糟糕的主意,因为C++ 标准中绝对不能保证这两种类型的大小相同。
如果您确实必须在整数类型和指针之间进行转换(这不是一个好主意,但有时没有其他选择),请使用 intptr_t
或 @987654325 @ 而不是 int
,因为它们保证与指针大小相同。这样您就不会收到任何警告。
作为旁注,像你这样的传统 C 转换在 C++ 中是不受欢迎的,因为你无法确定它们在幕后做了什么(可能是 static_cast
或 reinterpret_cast
,谁知道?)。更喜欢使用正确的 C++ 强制转换,即 reinterpret_cast
在您的情况下。
【讨论】:
对我来说,这个问题意味着fd
的类型是外部定义的,没有选择
@BalogPal:啊对,我错过了。但是我担心他们之间没有办法正确地投射。 ForEveR 的解决方案或 PlasmaHH 的评论可能是正确的。
pthread_create
具有固定签名,因此无法更改。但提问者可能会尝试将int
转换为intptr_tv and then to
void*`。
@WernerHenze:是的,我只是错过了问题中fd
的类型失控的部分。我的回答确实是解决一个必须像pthread_create
一样在void*
之间进行转换的情况。【参考方案3】:
您可以添加 static_assert(sizeof(fd) <= sizeof(void*), "problem")
之类的内容,并依赖 reinterpret_cast 将在这种情况下往返的实现文档。
【讨论】:
以上是关于使用 pedantic flag 编译时,如何在 C++ 中从 (void *) 重新输入到 int 而不会收到任何警告?的主要内容,如果未能解决你的问题,请参考以下文章
gcc编译选项pedantic(GCC编译器的C++标准严格模式)
是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?
如何禁用警告“省略局部变量的类型注释”?在 Dart 中(带有 Pedantic 包)
如何在 Vue 3.0 中通过 Webpack 使用 Bundler Build Feature Flags?