Почему значение этого uint32_t -2147483648?

Используя компилятор gcc, почему это uint32_t -2147483648 когда я установил MSB? Это без знака - не должно ли это быть положительным?

#include <stdio.h>
#include <stdint.h>

#define BIT_SET(a,b) ((a) |= (1<<(b)))

int main()
{
    uint32_t var = 0;
    BIT_SET(var, 31);

    printf("%d\n", var); //prints -2147483648

    return 0;
}

4 ответа

Решение

Тип var является uint32_t, Но вы печатаете это, используя %d который является неопределенным поведением. использование PRIu32 от <inttypes.h> печатать uint32_t:

printf("%"PRIu32"\n",var);

%d для целых чисел со знаком. Что вы хотите %u который для целых чисел без знака. printf не достаточно умен, чтобы угадать тип ваших данных.

Источник

printf() не знает, что именно вы передаете, и должен доверять вам, чтобы использовать правильный спецификатор преобразования. Но ты не. С %d, printf() интерпретирует вашу ценность как int,

На платформе, где unsigned int такой же как uint32_t (очень часто), вы можете использовать %u вместо. Но будьте осторожны, это не переносимо, например, на платформы, где int только 16 бит. Правильный способ распечатать uint32_t выглядит так (вы должны включить inttypes.h):

printf("%" PRIu32 "\n", var);

Смотрите, например, это inttypes.h ссылка

Вы используете неправильный спецификатор формата здесь. %d для int тип, т. е. целочисленный тип со знаком.

Чтобы напечатать точные переменные ширины, вам нужно использовать PRIuN макросы как спецификаторы формата.

Для 32-разрядного типа без знака это будет PRIu32, Для исчерпывающего списка, см. Главу §7.8.1, C11,

Другие вопросы по тегам