C: Как избавиться от ошибки преобразования?


У меня есть проект, который использует GCC версии 4.6.3, и я вынужден компилировать с "-Wall-Werror-Wconversion". Следующий простой пример показывает ошибку, от которой я не могу избавиться:

#include <stdint.h>

int main(void) {
  uint32_t u = 0;
  char c = 1;

  u += c;
  return (int)u;
}

Компиляция его с вышеуказанными флагами дает:

test.c:7:8: error: conversion to ‘uint32_t’ from ‘char’ may change the sign of the result [-Werror=sign-conversion]

Хорошо, хорошо. Просто добавьте типографию, верно? Нет. Изменение строки 7 на u += (uint32_t)c не приведет к исчезновению ошибки. Даже изменение его на u = u + (uint32_t)c не заставит его исчезнуть.

Можно ли это исправить?

Обратите внимание, что "char" - это исходит из строки, поэтому у меня нет возможности изменить ее тип.

3   4  

3 ответа:

Это прекрасно компилируется здесь:

u += (unsigned char)c;

Это только заставит замолчать предупреждение, однако - ничего не делая с каждым c во время выполнения, в отличие от предложения Базиля.

Проблема имеет знаковый (отрицательный) характер. Вы можете попробовать

 u += (unsigned) (c&0xff);

Вопрос в том, какое преобразование вы хотите. Если вы хотите, чтобы преобразование определялось стандартом, вам, по-видимому, нужно назначить c (временной) переменной uint32_t.

uint32_t temp = (uint32_t)c;
u += temp;

Работает по назначению (по крайней мере, с моим gcc-4.6.2).

Если это не является предполагаемым преобразованием - но почему вы тогда явно попросите об этом, используя (uint32_t)c? - решения, предложенные Базилем Старынкевичем или Михаилом Т., или флаг -funsigned-char устранят предупреждение.

ИМО это (ужасная) ошибка в gcc и clang, похоже, согласны, u += (uint32_t)c; работает так, как задумано.