Search code examples
cfunctioncastingfunction-pointersundefined-behavior

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


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?


Solution

  • 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();