Is it undefined behavior to “trash” a return value by casting the function pointer to a void function then calling it?

一曲冷凌霜 提交于 2020-06-17 00:09:43

问题


Say, something like this:

int SayHelloThenReturnTen(void) {
    puts("Hello world");
    return 10;
}

Then later:

((void(*)(void))SayHelloThenReturnTen)();

Is that safe? Is it safe to "trash" the return value by casting to a void pointer? Is this safe and cross platform, or is this undefined behavior?


回答1:


Is that safe?

It is safe to cast a function pointer to any function pointer type. Casting the result back to the original type will yield a pointer value equal to the the original pointer.

It is not safe, however, to call a function via a function pointer of a type incompatible with the function to which it points. This is set out pretty clearly in paragraph 6.3.2.3/8 of the standard:

A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.

(Emphasis added)

Is it safe to "trash" the return value by casting to a void pointer?

Your example does not demonstrate that. Rather, it demonstrates casting to a function pointer type with a void return type. Again, the cast is ok, but the call is not.

Is this safe and cross platform, or is this undefined behavior?

It is unsafe and has undefined behavior. Moreover, there is absolutely no benefit to be gained. You can simply ignore the function's return value if you wish. If you're trying to silence compiler warnings about doing that, then,

  1. consider that maybe the compiler has a point, and
  2. if you want to convey to the compiler that you really do want to ignore the return value, then it is clearer, simpler, and safe to cast that to void:

    (void) SayHelloThenReturnTen();
    



回答2:


This is undefined behavior because you are calling a function through an incompatible function pointer type.

If you don't want to use the return value, just don't use it:

SayHelloThenReturnTen();

Or cast the resulting expression to void:

(void)SayHelloThenReturnTen();



回答3:


Some implementations extend the language by specifying that taking the address of a function will yield a pointer to a machine code function that retrieve parameters and return its value (if any) in the manner documented by the execution environment, without regard for how it is actually called, and that and that a call made via function pointer will always be processed in the manner documented by the execution environment, without regard for what kind of function is targeted by the pointer. If processing a particular function call as described would result in a particular behavior, then such an implementation would define that as the behavior of that call, without regard for whether the Standard would require it to do so. On many such implementations, one may cast the address of a function like int dummy(void) { return 0;} to any function type which returns int or void, rather than having to write a separate dummy function for each signature.

The question of whether any particular implementation processes things in such a fashion, however, is outside the Standard's jurisdiction. Most implementations for common platforms will behave in that way when invoked with optimizations disabled, but the effect of enabling optimizations may be unpredictable.



来源:https://stackoverflow.com/questions/62313131/is-it-undefined-behavior-to-trash-a-return-value-by-casting-the-function-point

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!