如何在使用pedantic标志进行编译时从C ++中的(void *)重新输入到int而不会收到任何警告?

时间:2013-06-07 11:39:59

标签: c++ gcc compilation

我有mutlithread个客户端 - 服务器应用程序,通过sockets进行通信。 我用这种结构创建了新的线程:

 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并避免在编译期间发出任何警告?

3 个答案:

答案 0 :(得分:5)

发送指针有什么问题,而不是整数?将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函数中,这也不正确。

答案 1 :(得分:2)

int转换为void*然后再回到int是一个非常糟糕的主意,因为在C ++标准中绝对没有保证这两种类型的大小相同。

如果你真的必须在整数类型和指针之间进行强制转换(这不是一个好主意,但有时没有其他选择),请使用 intptr_t uintptr_t 代替int,因为它们可以保证与指针的大小相同。这样你就不会得到任何警告。

作为旁注,像C ++这样的遗留C强制转换在C ++中是不受欢迎的,因为你无法确定它们在幕后做什么(它可能是static_cast或{{1 }}, 谁知道?)。更喜欢使用适当的C ++强制转换,即你的reinterpret_cast

答案 2 :(得分:0)

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