2017-01-12 7 views
1

Я знаком с концепцией stdint.h в C. Явным образом указывая размер целого, заголовочный файл заменит целое число #define на соответствующее целое на этом компьютере. Например, если моя машина имеет 16-битные целые числа без знака, то uint32_t будет заменен на long unsigned int.Как вы определяете, поддерживает ли ваш аппарат стандартный целочисленный тип данных в C?

Однако предположим, что ваша машина поддерживает только до 32 битных целых чисел. Что произойдет, если вы использовали int64_t? Если этот целочисленный размер не поддерживается, как это будет устранено, так как нет замены, которая может его исправить?

Может быть, компилятор и ошибка говорят, что это невозможно решить? Или он попытается использовать два 32-битных распределения для хранения 64-битного типа данных?

+1

Существует компилятор C для 8-битного процессора (где регистры всего 8 бит) без сопроцессора Math. И они поддерживают 'long' и' float'. Ты можешь представить? – i486

ответ

5

Если какой-либо тип stdint не поддерживается, код не будет компилироваться. Вы можете проверить, если они поддерживаются как это:

#include <stdint.h> 

#ifndef UINT64_MAX 
#error uint64_t not supported 
#endif 

Если ваш компилятор поддерживает тип, но ваш процессор не делает, это означает, что некоторые библиотеки компилятора код получит молча ссылаться эмулировать больший тип.

Например, если вы используете uint32_t на 8-битном микроконтроллере, компиляторы имеют тенденцию его поддерживать, но поскольку тип только эмулируется с помощью программного обеспечения, полученный машинный код будет расти и замедляться.

+0

Любопытно, что' #ifndef UINT64_MAX', безусловно, хорош, но какая спецификация мешает другому коду определять 'UINT64_MAX' - в стороне от хорошей практики кодирования. – chux

+0

Is UINT64_MAX определяется stdint.h или это limit.h? – immibis

+0

@immibis stdint.h – Lundin

2

Компьютеры (процессоры) не ограничивают верхнюю ширину бита целочисленного типа. Компилятор устанавливает ограничения. Аппаратное обеспечение влияет на сложность и эффективность обработки больших целых типов. Даже 1-bit platform может выполнять 64-битную математику, учитывая достаточно времени и памяти.

Соответствующий C-компилятор C99, поддерживает целую ширину не менее 64 бит.

Да, 32-разрядная машина обычно обрабатывает 64-битные операции, используя пару 32-битных внутренних объектов.


Должно быть ясным. компилятор C99 должен обрабатывать некоторый целочисленный тип при наименее 64 бита для реализации требуемого long long. Платформа может или может быть реализована uint64_t, 64-битная ширина, без дополнений, целочисленный тип дополнения 2. Это очень часто реализуется.

unsigned long long ull; // must exist 

#include <stdint.h> 
uint_least64_t uleast64; // must exist 

uint64_t u64; // may exist 
+0

Соответствующие компиляторы не должны поддерживать до 64 бит, если машина по какой-то причине не может их обработать. 7.20.1.1 «Эти типы являются необязательными. Однако, если реализация обеспечивает целочисленные типы с ширинами 8, 16, 32 или 64 битов , без битов заполнения и (для подписанных типов), которые имеют представление двух дополнений, это определяет соответствующие имена typedef. " Например, не многие 8-битные компиляторы MCU поддерживают uint64_t. – Lundin

+0

Я понимаю, что процессор может выполнять любую арифметику размера любого размера, разбивая инструкции, однако, допустим, меня просто интересует чтение/запись из памяти. Если бы я попытался объявить указатель на int64_t в памяти, а затем решил разыменовать этот указатель, он мог бы разыменовать нормально? Или это будет только разыменовывать первое 32-битное целое число? – Izzo

+1

@Teague Если ваш компилятор поддерживает 'int64_t', то он будет работать так, как ожидалось. Он будет считывать данные по 32 бита за раз, а затем сохранять результаты в соответствии с контентом. Но чтение будет медленным и никогда не будет атомарным. – Lundin

1

Типы точной ширины, объявленные в конкретной реализации C stdint.h (как typedef s, а не макросы), являются необязательными. Реализации должны объявлять их только в том случае, если они фактически предоставляют тип данных с требуемыми характеристиками.

В вашем конкретном примере, если рассматриваемая реализация C не предлагает 64-битный двоичный целочисленный тип дополнения без битов заполнения, то его stdint.h не объявит тип int64_t. Если вы затем используете этот тип, не объявляя его самостоятельно, компилятор отклонит ваш код.

Необходимы некоторые другие типы, предоставляемые stdint.h; Соответствующие реализации определенно обеспечат их. Для необязательных можно проверить, предоставляет ли компилятор их, проверяя, определены ли соответствующие макросы для их пределов (например, INT64_MAX).