makecontext的参数

makecontext是一个变参函数,我们知道变参函数其实没有办法知道传进来的参数的类型(这就是为什么printf是类型不安全的),makecontext假定传进来大小是sizeof(int),我么有时候会需要传指针进去

这种做法在64位下会有点问题,64位下指针是8字节,而int只有4字节,这时需要把指针拆成两部分,传两个参数进去,再由回调函数组装成指针

详情说明见man makecontext

但是今天我在64位下直接使用指针传进去也成功了,网上有这么一段话:

The standard says the parameters must all be int values. This is 
an historic accident and would be done differently today. For 
x86-64 all integer values are passed as 64-bit values and 
therefore extending the API to copy 64-bit values instead of 
32-bit ints makes sense. It does not break existing 
functionality and it does not violate the standard which says 
that passing non-int values means undefined behavior.
这段话表示在x86-64架构下int都是通过64位传的,所以直接传入64位指针也不会有问题
当然,也有可能是因为指针的高位是0,稍后我会进行测试
 
另外,关于64位下数据类型的大小,wiki上说的很清楚了:

"在主要的 32位机器程序设计环境中,指针、“int”变量、“long”变量全部都是 32位长。

然而,在 64位机器下的许多程序设计环境,“int”变量仍然是 32位宽,不过“long”和指针是 64位宽,上述内容称为 LP64 。另一个选择是 ILP64 数据模型,三种数据型态都是 64位宽,甚至 SILP64 连“short”变量也是 64位宽。然而,大多数情况下所需的修改是相对次要且简单,而且许多编写良好的程序可以简单的重新编译给新的环境,而无须修改。另一个选择是 LLP64 模型,其维持 32位代码的兼容性,使 int 和 long 为 32位。“LL”指“long long”型态,其在所有平台下至少是 64位,包括 32位环境。

今天有许多 64位编译器使用 LP64 模型(包括 Solaris、AIX、HP、Linux、Mac OS X、IBM z/OS 原生编译器)。微软的 VC++ 编译器使用 LLP64 模型。其缺点是在 LP64 模型中将 long 存放到 int 可能会溢出。另一方面,还会使强制转型一个指针为 long 可以作用;在 LLP 模型下,情况则刚好相反。两者皆不应该出现在合乎 C99 的代码中。"

简而言之,对于linux/Windows编程,应该避免使用long,都用int,不应该将指针转换为int或者long(很容易做到)

 

posted @ 2013-05-10 12:00  mightofcode  阅读(1520)  评论(0编辑  收藏  举报