Когда нельзя использовать inttypes.h? - PullRequest
0 голосов
/ 24 сентября 2018

C99 и более поздние версии предоставляют заголовок inttypes.h, который определяет определения переносимых типов для целых чисел определенной ширины.Это более надежная гарантия, чем, например, стандарт C int, имеющий ширину не менее 16 бит и long int, имеющий ширину не менее 32 бит.

Предполагая, чтоВ проекте, который может работать с C99 или более поздней версией и не требующем, в частности, ANSI C89, существует ли какой-либо вариант использования, в котором использование inttypes.h и определенные в нем типы были бы неуместными, тем более что на первый взгляд эта библиотека кажется почти универсальным улучшением по сравнению с Cосновные int типы?

1 Ответ

0 голосов
/ 05 октября 2018

Одна проблема с типами C99 заключается в том, что, хотя их размеры определяются независимо от платформы, их поведение не определяется.Например, учитывая uint16_t a=3,b=4,c=5; int x= (a > b-c), для некоторых реализаций потребуется 1 (так как 3> -1), а для других потребуется 0 (так как 3u <65535u).Во многих случаях можно обойти такие ограничения, явно скрыв результаты операций, а во многих случаях написание кода, например, <code>(a > (uint16_t)(b-c)), (a > ((int)b-c) или (a > ((int32_t)b-c) [в зависимости от того, что на самом деле требуется вычислить]сделайте намерение более ясным.

С другой стороны, иногда целочисленные продвижения могут проявляться странным образом.Принимая решение о том, следует ли использовать короткие типы без знака как int со знаком или без знака, авторы C89 отметили, что в большинстве текущих реализаций арифметика со знаком и без знака будет вести себя идентично вне нескольких конкретных контекстов, даже в случаях, выходящих за рамкидиапазон 0..INT_MAX , но некоторые реализации стремятся использовать тот факт, что Стандарт на самом деле не требует этого.Может показаться, что что-то вроде:

unsigned mulMod65535(uint16_t x, uint16_t y) { return (x*y) & 0xFFFF; }

не должно иметь каких-либо побочных эффектов, но если gcc знает, что, например, y == 65535, он будет использовать это для распространения того факта, что x "не может"больше, чем 32768. Интересно, что существующие версии gcc, по-видимому, воздерживаются от такого предположения, если функция вернула uint16_t, но я не знаю ничего, что обещало бы, что будущие версии не будут более агрессивными.

...