关于void*与int的强制转换

在完成一次网络编程练习的时候,遇到了整数类型与指针类型转换的问题。
问题产生于函数
int pthread_create (pthread_t *, __const pthread_attr_t *, void *(*__start_routine) (void *), void *);
我需要给线程执行的函数传递一个套接口描述字,这样一来很容易想到
pthread_create(&tid, NULL, &DoSomething, (void*)&connFd)
的方式,当然考虑到线程共享的问题,connFd传入线程后会是什么值就很郁闷了。
我选择了在每创建线程之前,new一个int类型指针:   
ptr = new int();
*ptr = accept(listenFd, (sockaddr*)&addr, &len);
pthread_create(&tid, NULL, &DoSomething, (void*)ptr);

而线程中取值则可以直接使用int connFd = *((int*)arg);这样的写法了。 //arg为执行函数形参

这在UnixNetwork一书中是推荐的做法,相较而言,也是容易理解的写法。
而同学提到了另一种常见方式:   
connFd = accept(listenfd, (sockaddr*)&addr, &len);
pthread_create(&tid, NULL, &DoSomething, (void*)connFd);
取值时直接使用int connFd = (int)arg;
这便是题中所述的两处强制转换了,初看只是觉得很怪异,然后想到了64位机器。
最重要的一点,同学提到在windows的函数中这种用法太常见了,我想,Unix/Linux中也许同样常见才对吧。
在我的编译环境下,上述的代码是编译不通过的,error: cast from 'void*' to 'int' loses precision,编译器认为64bit指针转换为32bit整数是丢失精度的。故而我才转投了最初所写的那种方法。
思前想后几次,memcpy是种替代方案,编译器不让咱转,咱自己来:
int cast(void *arg)
{
int tmp;
memcpy(&tmp, (void *)&arg, 4); //这是最让我觉得它怪异的地方,本来把指针当作整型变量用了,要恢复就只能取地址,再加上参数是void*,这真是够整洁的。
return tmp;
}

折腾了几次,我还是在我的机器上老老实实用我的new吧,OMG,忘记回收内存了。。

PS:这里说的转换并不是真就把int当指针用,而只是取指针值本身&arg,但是它并未指向有意义的东西。

你可能感兴趣的:(关于void*与int的强制转换)