предупреждение: формат "% d" ожидает аргумент типа 'int *', но аргумент 3 имеет тип 'uint8_t * {он же без знака char *} - PullRequest
0 голосов
/ 30 сентября 2019

У меня возникает проблема, которая говорит:

warning: format ‘%d’ expects argument of type ‘int *’, but argument 3 has type ‘uint8_t * {aka unsigned char *}

, и я не уверен, почему это происходит, потому что я думал, что int и uint8_t взаимозаменяемы.

Вот мой код:

uint8_t** fileRead(char* file, int* pointer) {
    FILE* file = fopen(file, "r");
    int count = 0;
    pointer = &count;
    fscanf(file, "%d", &count); //this retrieves a single integer
    uint8_t** result = (uint8_t**) malloc(*pointer * sizeof(uint8_t*));
    while (file != NULL) {
        for (uint8_t i = 0; i < *pointer; i++) {
            uint8_t* a = (uint8_t*) malloc(sizeof(uint8_t));
            uint8_t* b = (uint8_t*) malloc(sizeof(uint8_t));
            uint8_t* c = (uint8_t*) malloc(sizeof(uint8_t));
            fscanf(file, "%d", a);
            fscanf(file, "%d", b);
            fscanf(file, "%d", c);
            if (a == NULL || b == NULL || c == NULL) {
                uint8_t* npointer = NULL;
                fclose(file);
                free(result);
                return NULL;
            } else {
                result[i][0] = *a;
                result[i][1] = *b;
                result[i][2] = *c;
                free(a);
                free(b);
                free(c);
           }
        }
    }
    return result; 
}

, и ошибки происходят в следующих строках:

fscanf(file, "%d", a);
fscanf(file, "%d", b);
fscanf(file, "%d", c);

Большое спасибо заранее

Ответы [ 4 ]

2 голосов
/ 30 сентября 2019

Я думал, что int и uint8_t взаимозаменяемы.

Они не - int (со знаком или без знака) должны иметь ширину не менее 16 бит (этоможет быть шире, но не уже) 1 . uint8_t, как следует из названия, имеет ширину 8 бит.

Вам необходимо использовать спецификатор формата %hhu для считывания числового значения в объект uint8_t или unsigned char.


Строго говоря, int должен иметь возможность представлять все значения в как минимум в диапазоне [-32767..32767]. Это требует как минимум 16 бит. Некоторые архитектуры (которые я никогда не использовал) имеют «биты заполнения», которые вносят вклад в размер слова, но не используются для хранения значения. Так, например, у вас может быть 9-битный компьютер с 18-битными словами, но реализация в этой системе может по-прежнему использовать 16 бит для представления значения `int` - два бита просто не используются,
2 голосов
/ 30 сентября 2019

Используйте "%hhu" в качестве спецификатора формата вместо "%d".

1 голос
/ 30 сентября 2019

При печати вы можете избежать использования %d в качестве спецификатора формата, поскольку uint8_t означает , запрашиваемое для int при передаче в функцию с переменным числом, например printf. Это продвижение, однако, не происходит для указателей, что scanf ожидает для большинства спецификаторов формата.

Спецификатор формата %d для scanf, как вы видели, ожидает int *. В большинстве систем вы можете встретить int 4 байта. Поэтому, когда scanf разыменовывает указатель, вы даете ему %d для записи значения, которое будет записывать 4 байта. Это ломается, если вы передаете uint8_t *, так как этот тип занимает только 1 байт. Используя %d, scanf будет думать, что вы передаете адрес int и записываете 4 байта, что на 3 байта больше конца данной переменной. Это вызывает неопределенное поведение .

. Чтобы исправить это, измените спецификатор формата на %hhu, что предполагает unsigned char *.

1 голос
/ 30 сентября 2019

Чтобы прочитать целое число в unsigned char с (f)scanf, вам нужно "%hhu".

...