Search code examples
ccastingstandardscalling-convention

Is it safe to call a function after casting it to a void return type?


I have a function that returns a value. Is it safe to cast it to a function pointer type that returns nothing (void) and then call it? Does the C standard give enough guarantees to make this safe on any platform, and equivalent to calling the function normally while ignoring the return value?

Bonus question: Is there a standards compliant calling convention that is used in practice on some platform and with which this is not safe to do?


Example code:

#include <stdio.h>

// simple function with a a side-effect;
// it is useful to call even when ignoring the return value
int f(int x) {
    return printf("%d\n", x);
}

typedef void (*fun_t)(int);

int main() {
    fun_t g = &f; // cast to void return type, issues a warning
    g(123);       // <-- is this safe, and equivalent to calling f(123) instead?
    return 0;
}

Notes:

  • This question is concerned only with changing the return type during the cast, not changing the types of any function parameters.
  • I know that this is safe on the x86 and x64 platforms I use, assuming the default calling convention, but I would like to know if it is safe in general.
  • I know that it is easy to work around this when necessary by writing a wrapper void fw(int x) { f(x); }. However, I would still like to know if doing this is safe so that I can better understand the fundamentals of the C language.

Solution

  • No.

    In addition to tstanisl's answer:

    Consider a big return value as for example this structure:

    struct big_t {
        long la[1000000];
    };
    

    It is allowed as a return type.

    Some compilers, including GCC for x86/x64, provide the space for the return value at the caller's site and call the function with a pointer to this space. In your use case, this pointer is not set.

    So it is not safe on x86 or x64, nor any other architecture.

    Have a lot of fun debugging the crashes!