简体   繁体   中英

C - struct with a function pointer, how to fix “variable number of arguments” warning?

I'm trying to get rid of warning: assignment from incompatible pointer type [-Wincompatible-pointer-types] while adding func2 in this simplified example of dealing with a huge open source C library - which has a lot of functions like func1 and defines like str1.func = func1; . Is it possible to fix this warning without modifying func1 or writing something specific for each function / its' defines?

This code at OnlineGDB - https://onlinegdb.com/ry5rNlvDG , click "Fork this" to modify

#include <stdio.h>

void func1(int a) { // please don't change
    printf("%i\n", a);
}

void func2(int a, char c) {
    printf("%i - %c\n", a, c);
}

struct bigstruct {
    // void (*func) (int a); // old way
    void (*func) (int a, char c); // ??? - some magic needed
};

int main()
{ 
    struct bigstruct str1, str2;

    str1.func = func1; // please don't change
    // ^^^ gives a warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
    str2.func = func2;

    error; // onlinegdb - error on purpose to see the warnings
}

UPDATE: eventually I figured out this is indeed impossible, but I got away from this situation just by adding a new field to the structure that has been passed around through this open source library from one function to another, and as result didn't have to add a new argument to the function. I'm giving top answer to "@Rarity" for his best attempt

With your "please don't change"s it is not possible. However, you could make a cast:

str1.func = (void(*)(int, char))func1;

The function will be called with 2 parameters but it takes only one. On Intel and VC the second parameter will be ignored. (Parameters are pushed right-to-left onto the stack and func1 will only access the first parameter and will be unaware of any other parameters higher on the stack). This could be different on other architectures.

I don't quite get your concern, if it's warning you're after, then -Wno-incompatible-pointer-types is probably ok.

Else, if you want to suppress warnings selectively, then change func declaration to:

struct bigstruct {
    void (*func) ();
};

, then func will accept various function pointers. Type void ()() in C is "function which takes unknown number of unknown arguments (and returns nothing)", unlike void()(void) which is "a function that takes no arguments".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM