C 跨不同平台使用void指针

C 跨不同平台使用void指针,c,pointers,void-pointers,format-specifiers,C,Pointers,Void Pointers,Format Specifiers,我听说应该首先将指针转换为void,以确保不同平台上的值的一致性,并且应该使用%p格式说明符。为什么会这样?到底是什么问题 int x=100; int *pi=&x; printf("value of pi is: %p",(void*)pi); printf是一个可变函数,必须传递正确类型的参数。标准规定%p采用无效* 因为 引用7.21.6.1中的fprintf函数 参数应该是指向void的指针。指针的值为 在定义的实现中转换为打印字符序列 态度 不同指针类型的内部表示形式或大小

我听说应该首先将指针转换为void,以确保不同平台上的值的一致性,并且应该使用
%p
格式说明符。为什么会这样?到底是什么问题

int x=100;
int *pi=&x;
printf("value of pi is: %p",(void*)pi);

printf
是一个可变函数,必须传递正确类型的参数。标准规定
%p
采用
无效*

因为

引用7.21.6.1中的fprintf函数

参数应该是指向void的指针。指针的值为 在定义的实现中转换为打印字符序列 态度


不同指针类型的内部表示形式或大小不一定相同

例如,在一个系统上,
sizeof(void*)
可以是2,但
sizeof(int*)
可以是1


由于
printf
是可变参数函数,因此它无法检查传入参数的类型。如果将
int*
传递给它,它将读取错误的字节数,因为它需要
void*
p
中的转换规范
printf
需要类型为
void*
的参数。C表示,如果传递其他类型的参数,调用将调用未定义的行为


除此之外,不同类型的指针对象不需要具有相同的表示形式:例如,C不保证
sizeof(void*)==sizeof(int*)
。C仅保证
void*
具有与字符类型指针相同的表示形式。

请注意,您的引用肯定是特定于POSIX的,IIRC标准要求两个不同的指针具有不同的特定于实现的输出。@MatteoItalia谢谢。更新。引用得很好,但实际上,隐式转换没有发生这一事实如何影响传递参数的值(换句话说,转换为
void*
如何使
pi
的值有所不同)?@barakmanos C规范不要求
void*
t*
(其中T是非void类型)相同。在指针指向
void
和指针指向(比如)int的情况下,可变实现可能决定推送不同数量的字节。但是
printf
会将此指针的值作为type
void*
获取,并将调用未定义的行为。我不会说“除此之外”,而是“那是因为”:如果#2不是这种情况,就没有理由使用#1。这意味着,如果所有指针在内存布局方面看起来彼此相似,就没有必要为非void
*
@glglglglgl指定UB,我仍然更喜欢“除此之外”因为除了C表示指向其他类型的指针不需要具有相同的表示或对齐要求外,
fprintf
函数还有一个特定的C规则,它说
p
的参数应该是一个指针
void*
。你是对的,但两者之间的相互检测仍然存在。我很好奇你能举一个系统或编译器的例子,其中
sizeof(void*)!=sizeof(T*)
T
)是任何东西吗?@lucastrezesniewski: