且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将函数指针强制转换为空有什么作用?

更新时间:2023-11-27 16:23:34

此代码需要诊断:

void (*CharBufferClear)(CharBuffer) = (void*) StdBufferClear;

您正在将void *指针转换为不带强制转换的函数指针.在C语言中,void *指针可以转换为指向对象类型的指针而无需强制转换,但是不能转换为函数指针类型. (在C ++中,为了增强安全性,还需要强制转换将void *转换为对象类型.)

You're converting a void * pointer to a function pointer without a cast. In C, a void * pointer can convert to pointers to object types without a cast, but not to function pointer types. (In C++, a cast is needed to convert void * to object types also, for added safety.)

您想要的只是在函数指针类型之间进行转换,即:

What you want here is just to cast between function pointer types, i.e.:

void (*CharBufferClear)(CharBuffer) = (void (*)(CharBuffer)) StdBufferClear;

然后,由于功能是不同的类型,因此您仍在进行相同类型的修饰.您正在尝试使用指向采用CharBuffer的函数的指针来调用采用StdBuffer的函数.

Then you are still doing the same type punning because the functions are different types. You are trying to call a function which takes a StdBuffer using a pointer to a function which takes a CharBuffer.

这种类型的代码不是定义明确的C.在击败类型系统之后,您自己一个人依靠测试,检查目标代码或从编译器作者那里获得某种保证,即这种方法是可行的那个编译器.

This type of code is not well-defined C. Having defeated the type system, you're on your own, relying on testing, examining the object code, or obtaining some assurances from the compiler writers that this sort of thing works with that compiler.

您在汇编程序编码中学到的知识不适用,因为汇编语言只有少量的基本数据类型,例如机器地址"或"32位字".汇编语言中不会出现具有相同布局和低级表示形式的两个数据结构可能是不兼容类型的概念.

What you learned in assembler coding doesn't apply because assembly languages have only a small number of rudimentary data types such as "machine address" or "32 bit word". The concept that two data structures with an identical layout and low-level representation might be incompatible types does not occur in assembly language.

即使两个类型在底层看起来相同(另一个示例:unsigned intunsigned long有时完全相同),C编译器也可以基于未违反类型规则的假设来优化程序.例如,假设AB指向相同的存储位置.如果为对象A->member分配对象,并且A->memberB->member具有不兼容的类型,例如一个为char *而另一个为B->member不受此影响. c8>.即使内存副本被分配给A->member覆盖,生成的代码仍将B->member的旧值缓存在寄存器中.这是无效的 aliasing 的示例.

Even if two types look the same at the low level (another example: unsigned int and unsigned long are sometimes exactly the same) C compilers can optimize programs based on the assumption that the type rules have not been violated. For instance suppose that A and B point to the same memory location. If you assign to an an object A->member, a C compiler can assume that the object B->member is not affected by this, if A->member and B->member have incompatible types, like one being char * and the other void *. The generated code keeps caching the old value of B->member in a register, even though the in-memory copy was overwritten by the assignment to A->member. This is an example of invalid aliasing.