2017-02-14 19 views
2
int main() 
{ 
    unsigned int c = -1; 
    char *s = "Abc"; 
    char *x = "defhe"; 
    ((strlen(s)-strlen(x))>c)? printf(s): printf(x); 
} 

значение c является 4294967295 и значение (strlen(s)-strlen(x)) является 4294967294 он должен напечатать x но печатает s value.I я не получаю, почему это так,неподписанных INT Comparision в с

+4

Не так ли странно поставить '-1' в неподписанном int в первую очередь? –

+0

Возможно, c не оценивается до этой строки и напрямую обменивается постоянным литералом -1, поэтому не происходит продвижение? –

+0

Эти 'printf' действительно странные. – Lopan

ответ

6

значение С 4294967295 и значение (STRLEN (ы) -strlen (х)) 4294967294

это не всегда верно, что дает (strlen(s)-strlen(x))4294967294. Это зависит от значения SIZE_MAX в вашей системе.

Если SIZE_MAX является 18446744073709551615 (как правило, на 64-битной системы), то (strlen(s)-strlen(x)) будет 18446744073709551614, который, очевидно, больше, чем 4294967295 (предполагается, что это UINT_MAX4294967295). Следовательно, вы получите printf(s);.

Используйте printf() заявления, чтобы увидеть значение и понять:

printf("%zu %u\n", strlen(s)-strlen(x), c); 
+0

cool .. thanks @usr –

+0

Добро пожаловать! – usr

+0

Из стандарта ANSI (у меня нет C99, но это то же поведение): A.6.2 Неопределенное поведение * Арифметическая операция недействительна (например, деление или модуль на 0) или дает результат, который не может быть представлен в пространстве (например, переполнение или нижнее течение) ($ 3,3). strlen() возвращает size_t без знака. Вы переполнены и в сферах неопределенного поведения. Я видел, что это противоречиво в операторах, скомпилированных одним и тем же компилятором, не говоря уже о компиляторе к следующему. – BigBobby

2

кажется, что вы выводимое выражение strlen(s)-strlen(x) с использованием спецификатора формата %u, например, как этот

printf("%u\n", (unsigned int)(strlen(s)-strlen(x))); 
printf("%u\n", c); 

В этом случае выходного действительно равна

4294967294 
4294967295 

Однако, если вы выводите эти выражения с помощью литья к типу size_t и спецификатора формата %zu вы получите

printf("%zu\n", strlen(s)-strlen(x)); 
printf("%zu\n", (size_t) c); 

и

18446744073709551614 
4294967295 

Таким образом, значение выражения strlen(s)-strlen(x) больше, чем значение из переменная c литой к типу size_t.

Вы можете получить ожидаемый результат, если sizeof(size_t) будет равно sizeof(unsigned int).

1

Этот тип неявного преобразования от int/unsigned int до size_t тип является склонным к ошибкам и его трудно обнаружить. Анализаторы статического кода, такие как PVS-Studio, очень хороши в поиске таких ошибок автоматически.

+0

Какое неявное преобразование? Единственное неявное преобразование, которое здесь происходит, - это 'c', получившее повышение до' size_t' в выражении '(strlen (s) -strlen (x))> c', что не имеет отношения к результату и к вопросу. – Lundin

+0

@ Lundin Не 'unsigned int c = -1;' также подразумевается преобразование 'int' в' unsigned'? (что также является второстепенным по отношению к теме сообщения) – chux

+0

@chux Ну да, но даже если он был написан как «-1u», это не повлияет на результат. Так что это не отвечает на вопрос. – Lundin