Как вы справляетесь с изменением собственного размера целых чисел между платформами?

Боюсь, я уже знаю ответ на этот вопрос, но хочу убедиться ...

У меня довольно большой проект с файлом заголовка, который определяет собственные типы:

typedef unsigned long int    u32;
typedef signed long int      s32;
// etc...

Случилось неизбежное, и теперь я пытаюсь скомпилировать систему, в которой long - это 64 бита вместо 32. Как лучше всего это исправить?

Я мог бы typedef вышеуказанное с int (или _5 _ / _ 6_ из stdint.h), который удовлетворял бы 32-битному размеру на платформах, о которых я знаю, но это все еще кажется сомнительным. Также существует проблема с функциями стиля printf, где использовалось %ld (компилятор жалуется и хотел бы вместо этого увидеть %d). Все это нужно было бы изменить, не так ли (возможно, с определениями в inttypes.h)?

Это кажется простым, но я хотел бы убедиться, прежде чем начать копаться в этом (исправление строк формата printf кажется сложной задачей).


person josec    schedule 30.08.2011    source источник
comment
В какой момент это действительно имеет значение? Почему ты не можешь просто использовать unsigned int? Это портативный, просто не предсказуемый размер.   -  person Kerrek SB    schedule 31.08.2011
comment
Ваш компилятор должен выдавать предупреждения, когда вы передаете %ld не-long, а с флагом вы должны иметь возможность превратить это предупреждение в ошибку. Это дает вам возможность все исправить.   -  person Dietrich Epp    schedule 31.08.2011
comment
@Dietrich: это нормально для большинства простых случаев, когда ваша строка формата является литералом прямо здесь, при вызове printf. Однако компилятор не помогает, когда строка формата поступает откуда-то еще, например, из набора локализованных строк. Это одна из причин, по которой рекомендуется использовать только %s в таких строках локализации и преобразовывать числа в строки перед включением кода, зависящего от языка, или использовать что-то более безопасное, чем varargs. Однако, если вы уже сделали это по-другому, нужно это изменить. Так что то, что вы говорите, стоит делать, но не все исправляет.   -  person Steve Jessop    schedule 31.08.2011
comment
@Steve Jessop: Честно, но обычно вы можете определить макрос для передачи локализованных строк как литералов, а остальные случаи относительно редки.   -  person Dietrich Epp    schedule 31.08.2011


Ответы (3)


В C есть <stdint.h>, а в C ++ 0x это <cstdint>. Для компиляторов, отличных от C ++ 0x, у вас есть <boost/cstdint.hpp>, если вы не против использования Boost. Заголовок <inttypes.h> также включает макросы для спецификаторов формата printf(), которые могут быть адаптированы для использования с <cstdint> типами. Если вы используете C ++, вам следует использовать <iostream>, и, следовательно, вам не нужно беспокоиться о типизированных спецификаторах формата.

person Jon Purdy    schedule 30.08.2011
comment
@Jon: вы всегда можете вырвать заголовок из Boost (сохранить лицензию ...), я полагаю, это довольно независимо ... - person Matthieu M.; 31.08.2011

создать единый перевод (.cpp), который компилируется с вашей библиотекой / исполняемым файлом. в нем используйте статические утверждения. если вам нужен конкретный размер, этот подход может подтвердить, соответствуют ли ваши объявления условиям, которым они должны соответствовать, прежде чем вы создадите связываемый / исполняемый двоичный файл, если среда когда-либо изменится.

затем включите предупреждения компилятора и исправьте то, что необходимо исправить.

person justin    schedule 30.08.2011

Решение относительно портативного 32-битного целого числа (и т.п.):

  • Определите свои собственные переносимые типы в каком-нибудь вручную созданном файле конфигурации или
  • Используйте stdint.h, который делает это за вас и гарантированно присутствует в любом компиляторе C, даже близком к C99.

Что касается printf, stdint.h предоставляет переносимые макросы для printf. Или просто используйте ввод-вывод C ++, и тогда вам не придется беспокоиться о printf форматах.

person David Hammen    schedule 30.08.2011
comment
Заголовок <stdint.h> не содержит макросов printf, которые можно найти в <inttypes.h>. - person Dietrich Epp; 31.08.2011