Целые числа фиксированной ширины в C++

Иногда мне нужно использовать целые числа фиксированной ширины для связи с внешними устройствами, такими как ПЛК. Я также использую их для определения битовых масок и выполнения битовых манипуляций с данными изображения. Насколько мне известно, стандарт C99 определяет целые числа фиксированной ширины, такие как int16_t. Однако компилятор, который я использую, VC++ 2008 не поддерживает C99, и, насколько мне известно, Microsoft не планирует его поддерживать.

Мой вопрос: как лучше всего использовать целые числа фиксированной ширины в С++?

Я знаю, что VC++ определяет нестандартные целые числа фиксированной ширины, такие как __int16, но я не решаюсь использовать нестандартный тип. Будет ли следующий стандарт C++ определять целые числа фиксированной ширины?


person Dani van der Meer    schedule 09.04.2009    source источник


Ответы (6)


В Boost есть определения типов для всех типов C99 и других: "Boost целочисленная библиотека"

person Hrvoje Prgeša    schedule 09.04.2009
comment
Обновление для настоящих читателей: C++11 теперь имеет типы фиксированного размера: en.cppreference.com /w/cpp/типы/целое число - person dkg; 09.11.2015

Вы можете обойти проблему с помощью некоторых директив #ifdef.

#ifdef _MSC_VER
   typedef __int16 int16_t
#else
   #include <stdint.h>
#endif
person mmx    schedule 09.04.2009
comment
К сведению будущих читателей, в MSVC 2010 есть <cstdint>! - person Cameron; 25.01.2013

Включите файл <stdint.h>, чтобы получить определения для таких типов, как uint16_t. VC++ не поставляется с <stdint.h> по умолчанию, но вы можете получить этот файл из нескольких мест. В Wikipedia перечислены некоторые из них, а Google найдет гораздо больше.

person Adam Rosenfield    schedule 09.04.2009
comment
Проблема в том, что stdint.h, как и большинство или все заголовки C и C++, зависит от реализации. Определения зависят от реализации. Любой случайный заголовок может работать нормально или не работать. - person David Thornley; 09.04.2009
comment
@David: Это хороший момент, но в данном случае файлы stdint.h, перечисленные на странице Википедии, на самом деле специально написаны для MSVC++. - person j_random_hacker; 09.04.2009
comment
Ах, так мы не говорим здесь о случайных заголовках. Хорошо. - person David Thornley; 09.04.2009

Будет ли следующий стандарт C++ определять целые числа фиксированной ширины?

да.

Как сказал Мехрдад, сейчас вы можете использовать #ifdefs. Альтернативой может быть сложная магия шаблонов. У Boost есть что-то в этом направлении, библиотека Boost Integer.

person Konrad Rudolph    schedule 09.04.2009

Я использовал общедоступную (не GPL — настоящая общедоступная) версию stdint.h от Дэнни Смита, доступную в пакете mingw:

Мне пришлось настроить эту версию для компиляции с помощью некоторых компиляторов, отличных от VC 8 (в основном VC6) - это сослужило мне хорошую службу.

Может быть, на днях я соберусь где-нибудь опубликовать свою версию, совместимую с VC6. Изменения были довольно незначительными — всего лишь некоторые трюки с макросами для использования ключевых слов, характерных для VC6, для 64-битных типов. Если вам не нужна поддержка VC6, возможно, вам подойдет версия mingw.

person Michael Burr    schedule 09.04.2009

Есть разные пути. Большинство сред считают, что short int являются 16-битными, а long int являются 32-битными. (long подразумевается, когда вы объявляете просто int.) Если вы typedef используете свой собственный тип int16, вы, вероятно, в конечном итоге будете использовать short int.

Другая возможность связана с битовыми полями в структурах. Вы можете сказать что-то вроде:

struct x {
    int a : 16;
    int b : 5;
    ...
};

И так далее. Если вы затем определите:

struct x myvar;
myvar.a = 54;

Вы можете быть уверены, что myvar.a будет содержать 16 бит, а myvar.b будет использовать 5; общий размер myvar округляется до того, что составляют все биты, плюс, конечно, размер любых других полей.

person Peter    schedule 09.04.2009
comment
Short обычно составляет 16 бит, а long в современных системах может быть 32 или 64 бита. long long почти всегда будет 64. - person David Thornley; 09.04.2009
comment
Дэвид прав. Если вы пойдете по этому пути, я бы по крайней мере включил что-то вроде assert(sizeof (short) == 2) где-нибудь в вашем коде. - person j_random_hacker; 09.04.2009
comment
Теоретически длинные могут быть 64-битными. Я никогда не работал с 64-битной машиной, но у меня сложилось впечатление, что большинство компиляторов по-прежнему сохраняют long на уровне 32 и вынуждают вас использовать long long для 64. Хитрость, я думаю, в том, что все это определяется реализацией независимо от соглашений. . - person Peter; 10.04.2009