C 跨不同平台使用void指针
我听说应该首先将指针转换为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的指针。指针的值为 在定义的实现中转换为打印字符序列 态度 不同指针类型的内部表示形式或大小
%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
会将此指针的值作为typevoid*
获取,并将调用未定义的行为。我不会说“除此之外”,而是“那是因为”:如果#2不是这种情况,就没有理由使用#1。这意味着,如果所有指针在内存布局方面看起来彼此相似,就没有必要为非void*
@glglglglgl指定UB,我仍然更喜欢“除此之外”因为除了C表示指向其他类型的指针不需要具有相同的表示或对齐要求外,fprintf
函数还有一个特定的C规则,它说p
的参数应该是一个指针void*
。你是对的,但两者之间的相互检测仍然存在。我很好奇你能举一个系统或编译器的例子,其中sizeof(void*)!=sizeof(T*)
(T
)是任何东西吗?@lucastrezesniewski: