Nano Hash - криптовалюты, майнинг, программирование

Как гарантировать длину 4 байта

В С++ есть ли способ гарантировать, что длина длинного 4 байта? Возможно, флаг компилятора для g++?

Мы повторно используем некоторый код Windows в программе Linux, и в Windows длина длинной составляет 4 байта, но на моей машине с Linux длина длины составляет 8 байтов. Мы не можем изменить все long на int, потому что это нарушит код Windows.

Причина, по которой мне нужно гарантировать, что long составляет 4 байта, заключается в том, что в некоторых частях кода у нас есть объединение структуры и массива символов, а при компиляции для 64-битного Linux массив символов не совпадает с другой структурой.

Вот несколько фрагментов кода для пояснения:

struct ABC {
    unsigned long  data1;
    unsigned short data2;
    unsigned short data3;
    unsigned char  data4[8];
};
//sizeof(ABC) (32 bit): 16, sizeof(ABC) (64 bit): 24

union ABC_U {
    ABC abc;
    unsigned char bytes[16];
};

РЕДАКТИРОВАТЬ:

Я забыл упомянуть, что эта проблема возникла только при попытке скомпилировать для 64-битной версии. Кажется, что Windows предпочитает хранить длинные 4 байта независимо от архитектуры, тогда как linux g++ обычно делает длинные того же размера, что и указатели.

Я склоняюсь к использованию uint32_t здесь, потому что эта конкретная структура не используется в коде Windows, и это не повлияет на программу глобально. Надеюсь, что нет других разделов кода, где это будет проблемой.

Я нашел флаг компилятора -mlong32, но это также заставляет указатели быть 32-битными, что нежелательно, и, поскольку это вызывает нестандартное поведение, вероятно, нарушит ABI, как упоминал PascalCuoq.

14.08.2013

  • Как насчет указания целочисленного размера в битах, например, uint64? 14.08.2013
  • @ user2613971: Или uint64_t, который имеет достоинство быть стандартным, хотя похоже, что ОП ищет int32_t. 14.08.2013
  • Для поддержки такого переключения ваша реализация должна поставлять альтернативную стандартную библиотеку, скомпилированную с помощью sizeof(long)==4. Но это не масштабируется: если у вас есть N таких опций, вам нужно отправить 2 ^ N реализаций стандартной библиотеки. 15.08.2013

Ответы:


1

Вместо использования int и long вы, вероятно, захотите создать заголовочный файл, который использует макросы typedef (предпочтительно) или препроцессора для определения общих имен типов, которые вы будете использовать.

#ifdef _WINDOWS
typedef unsigned long uint32;
#else
typedef unsigned int uint32;
#endif

В вашем союзе вы бы использовали uint32 вместо long.

Заголовочный файл stdint.h делает именно это, но не всегда устанавливается как стандартный заголовочный файл с каждым компилятором. Visual Studio (например) не имеет его по умолчанию. Его можно загрузить с http://msinttypes.googlecode.com/svn/trunk/stdint.h, если вы предпочитаете использовать его вместо этого.

14.08.2013
  • Visual Studio имеет его по умолчанию. 14.08.2013
  • @BenjaminLindley: я считаю, что последняя версия работает, но она новая. 14.08.2013
  • @Benjamin: Это зависит от того, какую версию VS вы используете. 14.08.2013
  • Что ж, он существует с 2010 года (до того, как он стал частью стандарта C++), и если вы говорите, что в Visual Studio его нет, в настоящем времени, без уточнения версии, я думаю, разумно предположить, что вы имеете в виду стандарт самое последнее коммерчески доступное издание. 14.08.2013
  • Это было только после того, как вы установили сервисный патч (SP2, если я правильно помню). Он не был установлен с оригинальной версией 2010 года. Дело в том, что он может быть установлен или не установлен, поэтому вы можете скачать его (если хотите использовать) или написать свой собственный. 14.08.2013

  • 2

    Вы можете использовать int32_t из stdint.h.

    14.08.2013
  • Я почти уверен, что этот заголовок не существует в окнах ниже определенной версии Visual Studio (2010?) 14.08.2013
  • @cppguy: Так что сворачивайте сами. 14.08.2013
  • Разве это не его проблема с самого начала? Он пытается убедиться, что у него правильный typedef? 14.08.2013
  • Вы можете посмотреть stackoverflow.com/questions/126279/, чтобы получить stdint.h для Visual Studio. 14.08.2013
  • Хотя это правильно, это не полный ответ. Смотрите мой ответ ниже для более подробной информации. 14.08.2013

  • 3

    Вы хотите, чтобы компилятор сгенерировал код, в котором long является 32-битным.

    Скомпилируйте всю кодовую базу с помощью -m32. Это сгенерирует код в старом наборе инструкций IA-32, который до сих пор широко поддерживается библиотеками (*), и где long традиционно является 32-битным, как int.

    (*) Возможно, вам потребуется установить эти библиотеки в вашем дистрибутиве Linux, и вам, возможно, придется попросить своих пользователей установить их.

    14.08.2013
  • Проблема в том, что мы используем библиотеку rpm, и если 32-битная программа использует эту библиотеку на 64-битной машине, база данных rpm может быть повреждена, и использование программ, которые обращаются к этим базам данных, становится проблематичным, например ням. 14.08.2013
  • @BrianSchlenker Ну, даже если бы можно было заставить long быть 32-битным с помощью параметра при создании кода x86-64, это нарушит ABI и предотвратит связывание с любой библиотекой, включая, помимо прочего, об/мин. Таким образом, ответ на ваш вопрос, дополненный этой информацией, звучит так: «Нет, невозможно заставить long быть 4 байта». 14.08.2013
  • Спасибо, это имеет смысл. Похоже, единственный способ — изменить тип с long на что-то другое и, надеюсь, не сломать код Windows. 14.08.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..