uintmax_t 保证是否需要保持函数指针?
uintmax_t
我知道这个:
以下类型指定无符号整数类型,能够表示任何无符号整数类型的任何值:uintmax_t
和
以下类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将比较原始指针:uintptr_t
并且一个void-Pointer可能不大,只能保存一个函数指针,因此uintptr_t也可能不足以容纳一个函数指针 .
不,不是一般的 . void* 因此 [u]intptr_t 仅保证足够宽以容纳对象指针,即指向对象类型的指针 . 在某些平台上,函数指针可以更宽,并且包含的信息不仅仅是函数的入口点 . 因此,在这样的平台上, void* 或 uintptr_t 没有足够的位来表示所需的所有信息 .
void*
[u]intptr_t
uintptr_t
在许多平台上,函数指针的宽度与对象指针的宽度相同,甚至可以允许它们从一个转换为另一个 . 但这是C标准的扩展,您必须检查平台文档 .
C标准中没有这样的保证 .
首先,不能保证任何指针都可以无损地转换为整数类型(NULL指针除外) . 确实 uintptr_t 必须能够无损地表示空指针(因此任何onject指针) . 但是,无法保证实现具有 uintptr_t ,因为它和 intptr_t 是可选的(第7.20.1.4节的最后一句) .
intptr_t
其次,函数指针不是对象指针,并且不一定可以将其转换为void指针并返回 . 因此,即使 uintptr_t 确实存在,它也可能不足以容纳函数指针 .
在X / Open System Interface(XSI)兼容实现(大多数Posix系统)上,您必须能够在void指针和函数指针之间进行转换,并且uintptr_t必须存在 . 那么在这种情况下,你确实有保证 . ( dlsym 系统接口需要void和函数指针之间的可转换性,该接口在第7期(2008)中从XSI移动到基本Posix . 但是,uintptr_t的存在仍然是XSI扩展 . )
dlsym
uintmax_t保证大到足以容纳函数指针吗?
没有保证的方式以及其他人的回答 .
然而,函数指针的大小确实存在,并且它确实具有位模式 . 如果足够大, uintmax_t 可以保持指针的位模式(可能更多) . 可以在编译时评估此大小测试 .
#include <assert.h> #include <stdio.h> #include <stdint.h> int foo(int x) { return x+x; } int main(void) { union { uintmax_t um; int (*fp)(int); } u = {0}; assert(sizeof u.um >= sizeof u.fp); // This assertion may fail u.fp = foo; uintmax_t save = u.um; printf("%ju\n", save); u.um = save; printf("%d\n", (*u.fp)(42)); return 0; }
产量
4198816 84
3 回答
不,不是一般的 .
void*
因此[u]intptr_t
仅保证足够宽以容纳对象指针,即指向对象类型的指针 . 在某些平台上,函数指针可以更宽,并且包含的信息不仅仅是函数的入口点 . 因此,在这样的平台上,void*
或uintptr_t
没有足够的位来表示所需的所有信息 .在许多平台上,函数指针的宽度与对象指针的宽度相同,甚至可以允许它们从一个转换为另一个 . 但这是C标准的扩展,您必须检查平台文档 .
C标准中没有这样的保证 .
首先,不能保证任何指针都可以无损地转换为整数类型(NULL指针除外) . 确实
uintptr_t
必须能够无损地表示空指针(因此任何onject指针) . 但是,无法保证实现具有uintptr_t
,因为它和intptr_t
是可选的(第7.20.1.4节的最后一句) .其次,函数指针不是对象指针,并且不一定可以将其转换为void指针并返回 . 因此,即使
uintptr_t
确实存在,它也可能不足以容纳函数指针 .在X / Open System Interface(XSI)兼容实现(大多数Posix系统)上,您必须能够在void指针和函数指针之间进行转换,并且uintptr_t必须存在 . 那么在这种情况下,你确实有保证 . (
dlsym
系统接口需要void和函数指针之间的可转换性,该接口在第7期(2008)中从XSI移动到基本Posix . 但是,uintptr_t的存在仍然是XSI扩展 . )没有保证的方式以及其他人的回答 .
然而,函数指针的大小确实存在,并且它确实具有位模式 . 如果足够大,
uintmax_t
可以保持指针的位模式(可能更多) . 可以在编译时评估此大小测试 .产量