C++ 将intptr\t传递给需要int的函数是否安全?

C++ 将intptr\t传递给需要int的函数是否安全?,c++,c,callback,function-pointers,C++,C,Callback,Function Pointers,更具体地说,如果我有以下函数指针类型: typedef void (*callback_type) (intptr_t context, void* buffer, size_t count); 我是否可以安全且无“未定义行为”地执行以下操作: ? 其中write()是系统调用(编辑:具有签名ssize\u t write(int-fd,const-void*buf,size\u-t count);,因此将int作为第一个参数),而fd是int文件描述符。我假设C和C++的答案是相同的,所以我

更具体地说,如果我有以下函数指针类型:

typedef void (*callback_type) (intptr_t context, void* buffer, size_t count);
我是否可以安全且无“未定义行为”地执行以下操作:

?


其中
write()
是系统调用(编辑:具有签名
ssize\u t write(int-fd,const-void*buf,size\u-t count);
,因此将
int
作为第一个参数),而
fd
int
文件描述符。我假设C和C++的答案是相同的,所以我都在标记。

< p>问题不是函数之间来回传递参数,因为从一个整型到另一个积分类型自动完成。 问题是,如果
intptr\u t
int
短,那么
int
的每个值都不能用
intptr\u t
表示,该怎么办?在这种情况下,
int
中的一些最高位在转换为
intptr\t
时将被截断,因此您最终将
write()
写入无效的文件描述符。虽然这不应该调用未定义的行为,但它仍然是错误的。

否 这是不可移植的,因为您正在传递一个参数,该参数在通用LP64范例中的大小不同

此外,您没有使用正确的类型取消引用函数指针,并且其结果未定义

现在,正如您所总结的,函数指针将按预期工作,唯一的实际问题是:write(2)如何解释
intptr\t
第一个参数


而实际的运行时问题是,在LP64上,您将64位值传递给32位参数。这可能会使后续参数不对齐。在带有寄存器参数的系统上,它可能工作得很好。

让我们看看C标准

C11(n1570),§6.3.2.3指针 指向一种类型函数的指针可以转换为指向 功能的另一种类型,并再次返回;结果应进行比较 等于原始指针。如果使用转换的指针调用 其类型与引用类型不兼容的函数 行为是未定义的

C11(n1570),§6.7.6.3功能声明器(包括原型) 对于要兼容的两种功能类型,两者均应规定兼容 返回类型。此外,参数类型列表(如果两者都存在), 应在参数数量和省略号的使用上达成一致 终结者;相应参数应具有兼容类型

C11(n1570),§6.2.7兼容型和复合型 如果两种类型的类型相同,则它们具有兼容的类型

结论:

void (*) (intptr_t context, void* buffer, size_t count);
无法转换为:

void (*) (int context, void* buffer, size_t count);

你的要求似乎与标题的要求相反。编辑:啊,系统调用采用
int
。嗯,
context
属于
intptr\u t
类型,正在传递给
write
,该类型需要
int
。对我来说似乎是对的…嗯?此时,您正在将
intptr\u t
传递给需要
intptr\u t
的函数。那么问题出在哪里呢?你担心的部分是什么?从
&write
callback\u type
的转换,从
fd
intptr\t
的转换,或者其他什么?@lvella您没有解释
write
int
作为其第一个参数。对
func\u ptr
的赋值是否正确编译?如果是这样,那么在您的计算机上,
intptr\t
必须是
int
,否?@sftrabbit:赋值涉及重新解释强制转换,因此它将编译转换是否有效。如果
intptr\u t
不是
int
,你会得到未定义的行为。
intptr\u t
的要点不就是能够同时容纳
int
和指针吗?@lvella要点是它是一个整数类型,保证足够大,可以容纳指针。但是不能保证它能保存什么类型的整数。保证类型本身是一个整数type@lvella据我所知,
intptr\u t
是一种保证能够容纳指针的整数类型,而不是其他类型。标准中是否有要求
sizeof(T*)@H2CO3的要求?我不知道。@sftrabbit谢谢。对,那么这是一个真正的问题。
void (*) (int context, void* buffer, size_t count);