Игнорировать предупреждения «инициализация из несовместимого типа указателя»? - PullRequest
4 голосов
/ 19 ноября 2009

Существует ли директива компилятора, чтобы игнорировать предупреждения "инициализация из несовместимого типа указателя" в Hardware_MouseDrivers_GPM_Methods и Hardware_MouseDrivers_DevInput_Methods? Однако отключить глобальные предупреждения нельзя.

#include <stdio.h>

/* Mouse driver interface */

typedef struct _Hardware_MouseDriver {
        int (*open)(void*, char *);
        int (*close)(void*);
        int (*poll)(void*);
} Hardware_MouseDriver;

/* GPM */

typedef struct _Hardware_MouseDrivers_GPM {
        char *path;
} Hardware_MouseDrivers_GPM;

static int Hardware_MouseDrivers_GPM_Open(Hardware_MouseDrivers_GPM *this, char *path);
static int Hardware_MouseDrivers_GPM_Close(Hardware_MouseDrivers_GPM *this);
static int Hardware_MouseDrivers_GPM_Poll(Hardware_MouseDrivers_GPM *this);

static int Hardware_MouseDrivers_GPM_Open(Hardware_MouseDrivers_GPM *this, char *path) {
        printf("GPM: Opening %s...\n", path);
        this->path = path;
}

static int Hardware_MouseDrivers_GPM_Close(Hardware_MouseDrivers_GPM *this) {
        printf("GPM: Closing %s...\n", this->path);
}

static int Hardware_MouseDrivers_GPM_Poll(Hardware_MouseDrivers_GPM *this) {
        printf("GPM: Polling %s...\n", this->path);
}

Hardware_MouseDriver Hardware_MouseDrivers_GPM_Methods = {
        .open  = Hardware_MouseDrivers_GPM_Open,
        .close = Hardware_MouseDrivers_GPM_Close,
        .poll  = Hardware_MouseDrivers_GPM_Poll
};

/* DevInput */

typedef struct _Hardware_MouseDrivers_DevInput {
        char *path;
} Hardware_MouseDrivers_DevInput;

static int Hardware_MouseDrivers_DevInput_Open(Hardware_MouseDrivers_DevInput *this, char *path);
static int Hardware_MouseDrivers_DevInput_Close(Hardware_MouseDrivers_DevInput *this);
static int Hardware_MouseDrivers_DevInput_Poll(Hardware_MouseDrivers_DevInput *this);

static int Hardware_MouseDrivers_DevInput_Open(Hardware_MouseDrivers_DevInput *this, char *path) {
        printf("DevInput: Opening %s...\n", path);
        this->path = path;
}

static int Hardware_MouseDrivers_DevInput_Close(Hardware_MouseDrivers_DevInput *this) {
        printf("DevInput: Closing %s...\n", this->path);
}

static int Hardware_MouseDrivers_DevInput_Poll(Hardware_MouseDrivers_DevInput *this) {
        printf("DevInput: Polling %s...\n", this->path);
}

Hardware_MouseDriver Hardware_MouseDrivers_DevInput_Methods = {
        .open  = Hardware_MouseDrivers_DevInput_Open,
        .close = Hardware_MouseDrivers_DevInput_Close,
        .poll  = Hardware_MouseDrivers_DevInput_Poll
};

/* Test drivers */

void TestDriver(Hardware_MouseDriver driver, void *data) {
        /* Access the driver using a generic interface
         * (Hardware_MouseDriver) */
        driver.poll(data);
}

void main() {
        Hardware_MouseDrivers_GPM gpm;
        Hardware_MouseDrivers_DevInput devinput;

        Hardware_MouseDrivers_GPM_Open(&gpm, "/dev/gpmctl");
        Hardware_MouseDrivers_DevInput_Open(&devinput, "/dev/input/mice");

        TestDriver(Hardware_MouseDrivers_GPM_Methods, &gpm);
        TestDriver(Hardware_MouseDrivers_DevInput_Methods, &devinput);

        Hardware_MouseDrivers_GPM_Close(&gpm);
        Hardware_MouseDrivers_DevInput_Close(&devinput);
}

Ответы [ 3 ]

5 голосов
/ 19 ноября 2009

Приведите назначения к соответствующим типам (указатели на функции с void * вместо указателя вашего экземпляра):

 .open= (int (*)(void*, char *))Hardware_MouseDrivers_GPM_Open;

Или создайте тип и используйте его при определении и инициализации структуры:

typedef int (*openfcnt_t)(void*, char *);

typedef struct _Hardware_MouseDriver {
        openfnct_t open;
} Hardware_MouseDriver;

, а затем

 .open= (openfnct_t)Hardware_MouseDrivers_GPM_Open;

РЕДАКТИРОВАТЬ:

Если подумать, то самый простой и наименее сложный способ для программы на C будет:

 .open= (void *)Hardware_MouseDrivers_GPM_Open;
1 голос
/ 19 ноября 2009

Полагаю, очевидным ответом на этот вопрос является вопрос «почему бы не исправить код, чтобы использовать правильный тип указателя»?

EDIT

Хорошо, я могу понять, что вы не хотите усложнять код без необходимости, но я не думаю, что это слишком сложное или даже ненужное осложнение.

Давайте посмотрим на поле open в структуре Hardware_MouseDriver , которое должно быть указателем на функцию, которая принимает указатель на void в качестве первого аргумента.

Для инициализации этого поля вы используете указатель на функцию Hardware_MouseDrivers_GPM_Open , а в другом месте указатель на функцию Hardware_MouseDrivers_DevInput_Open . Ни один из них не принимает указатель на void в качестве первого аргумента, и это, конечно, то, о чем предупреждает компилятор.

Теперь, , если указатель void имеет тот же размер, что и эти указатели, и нет других удивительных различий между тем, как они хранятся и обрабатываются, при вызовах этих функций через open указатель будет работать как положено. Вполне вероятно, что так и будет, и я предполагаю, что с этим типом низкоуровневого кода маловероятно, что кто-то перенесет его на TOPS-20 или что-то еще. Но нет никаких гарантий, что это будет работать, и это выглядит (для меня) странно. (И компилятору, очевидно!)

Поэтому я предлагаю изменить код следующим образом:

static int Hardware_MouseDrivers_GPM_Open(Hardware_MouseDrivers_GPM *this, char *path) {
    printf("GPM: Opening %s...\n", path);
    this->path = path;
}

чуть более сложным:

static int Hardware_MouseDrivers_GPM_Open(void *arg1, char *path) {
    Hardware_MouseDrivers_GPM *this = arg1;
    printf("GPM: Opening %s...\n", path);
    this->path = path;
}

Я думаю, что это изменение будет проще и менее сложным, чем (1) отключение предупреждений, (2) его документирование, чтобы читатели могли понять, почему это предупреждение не считается здесь важным, (3) документирование его еще поэтому ваши читатели действительно верят, что вы знаете, что делаете, и (4) решаете проблемы, которые могут возникнуть, если кто-то на самом деле сделает портирует ваш код на TOPS-20.

0 голосов
/ 09 марта 2019

У меня была эта проблема, и после тщательного изучения я решил, что не должен был получать это сообщение. Подобные строки в структуре не генерировали эту ошибку.

Использование (void *) function_name исправлено.

Это избавило меня от необходимости исследовать дерево gcc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...