размер встроенных типов зависит от платформы
От: maks1180  
Дата: 29.01.22 02:35
Оценка:
Заметил, что размер встроенного типа зависит от платформы компилирования, например:
1) тип "long" на Linux(gcc) имеет размер 4/8 байт для x32/x64 платформы, но на Window(gcc или VS2015) всегда 4 байта!
2) тип "wchar_t" на Linux(gcc) имеет размер 4 байт, но на Window(gcc или VS2015) 2 байта!

например DWORD определён как "typedef unsigned long" и получается что на Linux x64 он будет 8 байт, и это вызывает ошибки.

Почему встроенные типы зависят от платформы ?
===============================================
(реклама, удалена модератором)
Отредактировано 29.01.2022 2:37 maks1180 . Предыдущая версия . Еще …
Отредактировано 29.01.2022 2:36 maks1180 . Предыдущая версия .
Re: размер встроенных типов зависит от платформы
От: andrey.desman Россия  
Дата: 29.01.22 03:48
Оценка: +2
Здравствуйте, maks1180, Вы писали:

M>размер встроенного типа зависит от платформы компилирования


Это данность. Стандарт определяет минимум битов на тип, не точное значение. Если хочется точного, то есть int8_t, int16_t, int32_t, int64_t.

M>например DWORD определён как "typedef unsigned long" и получается что на Linux x64 он будет 8 байт, и это вызывает ошибки.


Это какая-то виндовая штука. Думаю, определена она будет для совместимости как uint32_t или int32_t.

M>Почему встроенные типы зависят от платформы ?

Так повелось. Смотри data models вот тут:
https://en.cppreference.com/w/cpp/language/types
Re: размер встроенных типов зависит от платформы
От: Андрей Тарасевич Беларусь  
Дата: 29.01.22 06:29
Оценка: 3 (1) +2 -1
Здравствуйте, maks1180, Вы писали:

M>Почему встроенные типы зависят от платформы ?


Так устроены языки С и С++.

Во-первых, изначальная идея заключалась в том, что тип `int` будет фокальной точкой системы целочисленных типов этих языков и его размер будет совпадать с размером наиболее эффективно поддерживаемого целочисленного типа данной платофрмы, т.е. фактически совпадать с размером слова данной платформы. Ясно, что размер слова может быть разным на разных платформах, что и подразумевает отличия в натуральных размерах типов.

Как вы все знаете, эта здравая идея потом разбилась о рифы глупой и ленивой идеи "бинарной совместимости", в результате чего тип `int` сегодня является 32-битным даже на платформах с 64-битным словом.

Во-вторых, идея заранее заданного фиксированного рзамера каждого типа нежизнеспособна уже потому, что не все платформы поддерживают все размеры. Понимание этого факта и сегодня выливается в то, что библиотечные типы фиксированных размеров, вроде `int16_t`, являются лишь опционально поддерживаемыми.
Best regards,
Андрей Тарасевич
http://files.rsdn.org/2174/val.gif
Отредактировано 29.01.2022 6:37 Андрей Тарасевич . Предыдущая версия .
Re: размер встроенных типов зависит от платформы
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 29.01.22 08:00
Оценка: -3
Здравствуйте, maks1180, Вы писали:

M>Почему встроенные типы зависят от платформы ?


Потому, что могут, не?
Маньяк Робокряк колесит по городу
Re[2]: размер встроенных типов зависит от платформы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 29.01.22 18:53
Оценка: 15 (1)
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Во-первых, изначальная идея заключалась в том, что тип `int` будет фокальной точкой системы целочисленных типов этих языков и его размер будет совпадать с размером наиболее эффективно поддерживаемого целочисленного типа данной платофрмы, т.е. фактически совпадать с размером слова данной платформы. Ясно, что размер слова может быть разным на разных платформах, что и подразумевает отличия в натуральных размерах типов.


АТ>Как вы все знаете, эта здравая идея потом разбилась о рифы глупой и ленивой идеи "бинарной совместимости", в результате чего тип `int` сегодня является 32-битным даже на платформах с 64-битным словом.


В случае как минимум x86, SystemZ, MIPS (AFAIR) и частично ARM, int оставили 32-битным — потому что по-прежнему заметная часть операций может выполняться в 32 битах (x86-64 продолжает иметь 32 бита умолчанием для всего кроме адресных операций). В этом смысле, нет чёткого понятия "слово" у этих платформ, его отождествление с размером адреса некорректно.

(Я уж не вспоминаю, что в документации Intel словом продолжают называть 16 бит. На System/Z, MIPS, ARM, слово это 32 бита.)

Поэтому ссылаться на бинарную совместимость тут достаточно бессмысленно. Если бы была строгая бинарная совместимость, то случилось бы как c Windows, где в x86-64 продолжают сохранять long 32-битным — вот это уже точно полная глупость. (Характерно, что эту глупость не повторили в C#, где long 64-битный.)
А у названных — по-прежнему выполняется (частично или полностью) как раз то, что вы говорили:

AT> его размер будет совпадать с размером наиболее эффективно поддерживаемого целочисленного типа данной платофрмы


Для x86-64 это 32 бита, а не 64 (все команды на байт короче).
Для System/Z это 32 бита, а не 64 (большинство команд в 2 и 4 байта, а не G-группа S/390, где 6 байт).
И так далее.

Вот в случае, например, RISC-V уже не так — основной набор команд 64-битный, а 32 бита в RV64 используются ограниченно. Там, возможно, имело бы смысл думать о введении 64-битного int, но действительно сработала (наверняка) идея совместимости с соседними платформами. В любом случае, недостатки этого решения весьма малы.

АТ>Во-вторых, идея заранее заданного фиксированного рзамера каждого типа нежизнеспособна уже потому, что не все платформы поддерживают все размеры. Понимание этого факта и сегодня выливается в то, что библиотечные типы фиксированных размеров, вроде `int16_t`, являются лишь опционально поддерживаемыми.


Не думаю, что можно найти платформу общего назначения, где бы не было int16_t. Даже если операции выполняются в 32- или 64-битном int, этот тип для хранения продолжает использоваться.
Re: размер встроенных типов зависит от платформы
От: Pzz Россия https://github.com/alexpevzner
Дата: 29.01.22 19:03
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Почему встроенные типы зависят от платформы ?


По определению. Например, long определен стандартом, как удобный для платформы тип, размером не менее 32-х бит (на самом деле, размер задан не битами, а диапазоном значений). А для int гарантируется диапазон значений, соответствующий как минимум 16-и битам, хоть на большинстве популярных платформ он и равен, фактически, 32-м битам.

Почему линух и венда некоторые типы определяет по-разному, вопрос скорее исторический, чем технический.
Re: размер встроенных типов зависит от платформы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 29.01.22 19:13
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Заметил, что размер встроенного типа зависит от платформы компилирования, например:

M>1) тип "long" на Linux(gcc) имеет размер 4/8 байт для x32/x64 платформы, но на Window(gcc или VS2015) всегда 4 байта!

M>2) тип "wchar_t" на Linux(gcc) имеет размер 4 байт, но на Window(gcc или VS2015) 2 байта!


M>например DWORD определён как "typedef unsigned long" и получается что на Linux x64 он будет 8 байт, и это вызывает ошибки.


Если это именно виндовый DWORD, это некорректность определения. Он должен быть uint32_t, а вот во что мапится uint32_t уже должно зависеть от платформы. Рекомендую отправить багрепорт.
Но весь код Unix мира, который я вижу и который работает с типами Windows, давно перешёл на явное указание размера.

M>Почему встроенные типы зависят от платформы ?


С, C++ рассчитаны под очень много разных платформ. Стандарт определяет соотношение размеров (char ⊆ short ⊆ int ⊆ long ⊆ long long) и минимальный размер каждого (определён в минимальном размахе крайних значений, но по сути минимум битности: char — 8, short и int — 16, long — 32 и long long — 64).

Дальше действуют рекомендации (de facto, даже если явно не вписаны всякими ISO):
1) Естественная двоичная иерархия размеров приводит к фиксации на 8-16-32-64-128 бит (и не даёт создавать всякие 29 бит, это вам не мир Гарри Поттера).
2) int должен быть меньшим из нативно без сложного урезания поддерживаемым естественно на целевой платформе, а long — бо́льшим.
3) Для современного не-embedded, int должен быть 32 бита, а не 16, потому что все стали хотеть, чтобы в int влезали значения порядка миллионов. GNU явно пишет в своих рекомендациях "мы считаем, что int у́же 32 бит не бывает".

И вот тут возникает проблема как раз с размером long. При адресации N бит обычно есть и типы данных на >=N бит (перекосы сегментной адресации x86, или менее известной в POWER, SystemZ, в которых 16-битный address space number, не считаем). Если 64 бита в адресе, то есть и вычисления на 64 бита. Значит, long должен быть 64 бита. Unix с LP64 моделью — именно так. Дотнет в лице C# — тоже, хоть он и не "светит" реальный размер адреса. Но это естественно несовместимо с 32-битным режимом, где long был 32 бита. Значит, надо переходить к именованным размерам. Именно поэтому в C99 придумали всякие int32_t — чтобы завязывались на них в платформенно-зависимых местах, при сетевом взаимодействии и т.д.

И вот тут возникает вопрос с диверсией от Windows. Вместо, может быть, чуть более сложного на старте, но пути без дурного легаси, там сделали, что в 64 битах long остаётся 32-битным. Пример обзора для программистов. Авторы этого решения, похоже, сделали не только эту чушь — знаменитая статья (тут тоже обсуждалась). Если вы поддерживаете решение, принятое в Windows... мои соболезнования, но согласиться не могу аж никак.
Re: размер встроенных типов зависит от платформы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 29.01.22 19:26
Оценка:
Здравствуйте, maks1180, Вы писали:

И вдогонку:

M>Почему встроенные типы зависят от платформы ?


Более общая проблема тут в том, что вообще заточка на конкретный размер типа в таких понятиях, как и само наличие чего-то вроде неуточнённого int — это тяжёлое легаси древних средств, мощность которых была в сотни тысяч и в миллионы раз меньше нынешних и в которых какие-то int использовались только от бедности.

Правильная постановка любой задачи должна содержать конкретный диапазон значений, который уже компилятором отображается оптимальным образом на аппаратуру. Например, если у вас температура воздуха от -50 до +80, то так и надо писать, а не думать, int8_t, int или long. Компилятор, в зависимости от требуемых действий, подберёт, как её хранить и обрабатывать. И он должен, если требуется (а, может, и по умолчанию), вставлять проверки корректности операций (например, что у вас при инкременте не случилось переполнения).

По этому пути шли Pascal и сейчас есть Ada, но их сообщество программистов зарезало, IMO, за не-хакерскость в случае Pascal (и за дороговизну средств в случае Ada 1980-х). C и C++ представляют здесь собой тошнотворный гибридный костыль: молчаливое усечение для unsigned и опора на отсутствие нарушений домена для signed. Оба периодически вылазят боком, но по-разному.

Для внешнего общения, конечно, нужны типы с конкретной битностью. Но и для них должно быть гибче, чем просто 8/16/32/64. По этому пути пошёл LLVM, позволяя все размеры от 1 до 2048 бит, и GCC со своими overflow builtins. Осталось дождаться поддержки в мейнстримовых языках. А для внутреннего — вас не должно волновать, что такое int на конкретной платформе, пока хранение и операции выполняются за вас с соблюдением корректности (обеспеченной или при компиляции, или при выполнении).
Re[2]: размер встроенных типов зависит от платформы
От: Evgeny.Panasyuk Россия  
Дата: 30.01.22 04:02
Оценка:
Здравствуйте, netch80, Вы писали:

N>IMO, за не-хакерскость в случае Pascal


Ну вот такая примитивная и вездесущая штука как динамический массив в Pascal'е только через struct-хак и была доступна.
Re[3]: размер встроенных типов зависит от платформы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 07:04
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

N>>IMO, за не-хакерскость в случае Pascal


EP>Ну вот такая примитивная и вездесущая штука как динамический массив в Pascal'е только через struct-хак и была доступна.


Да, это не единственное, что было криво в исходном Паскале. Но это исправили в потомках. А вот переход на C вместе с водой выплеснул и ребёнка. Сейчас использование доменных целочисленных типов (диапазоном или набором значений) восстанавливают, но очень медленно, и легаси этому сильно мешает.
Отредактировано 30.01.2022 7:34 netch80 . Предыдущая версия .
Re[3]: размер встроенных типов зависит от платформы
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 07:21
Оценка:
Здравствуйте, netch80, Вы писали:

N>Не думаю, что можно найти платформу общего назначения, где бы не было int16_t. Даже если операции выполняются в 32- или 64-битном int, этот тип для хранения продолжает использоваться.


С и С++ широко используются не только на "платформах общего назначения".
Best regards,
Андрей Тарасевич
http://files.rsdn.org/2174/val.gif
Re[4]: размер встроенных типов зависит от платформы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 07:32
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, netch80, Вы писали:


N>>Не думаю, что можно найти платформу общего назначения, где бы не было int16_t. Даже если операции выполняются в 32- или 64-битном int, этот тип для хранения продолжает использоваться.


АТ>С и С++ широко используются не только на "платформах общего назначения".


И сколько таких платформ осталось в реальном доступе и какая часть из них актуальна для текущего обсуждения?
Да, для полной строгости надо было упомянуть сразу, что на самом деле для внутренней работы предназначены варианты least и fast. В отличие от точных типов intN_t, они обязательны начиная с C99 (хотя отсутствие int16_t имеет смысл только там, где или байт в 32 бита, как на Cray, или если байт не 8-битный — таки сколько таких осталось?) Но я не думал, что кто-то всерьёз будет за это цепляться, особенно в контексте данной темы.

И, я так понял, к остальной части возражений нет. Спасибо.
Re[5]: размер встроенных типов зависит от платформы
От: Андрей Тарасевич Беларусь  
Дата: 30.01.22 07:41
Оценка: :)
Здравствуйте, netch80, Вы писали:


N>>>Не думаю, что можно найти платформу общего назначения, где бы не было int16_t. Даже если операции выполняются в 32- или 64-битном int, этот тип для хранения продолжает использоваться.


АТ>>С и С++ широко используются не только на "платформах общего назначения".


N>И сколько таких платформ осталось в реальном доступе и какая часть из них актуальна для текущего обсуждения?


Именно им текущее обсуждение и посвящено.

Что касается фактической актуальности — это не имеет никакого значения. Как только такие платформы потеряют свою актуальность, их поддержка будет убрана из стандарта языка, как это произошло, например, с прямым и обратным кодами в представлении знаковых целых.

А пока нюансы, направленные на поддержку этих платформ, присутствуют в спецификации языка, никаких разглагольствований об их "актуальности" не будет. Все здесь, без единого исключения, незыблемо убеждены в безграничной важности и критической актуальности таких платформ.
Best regards,
Андрей Тарасевич
http://files.rsdn.org/2174/val.gif
Re[6]: размер встроенных типов зависит от платформы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 07:47
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

N>>>>Не думаю, что можно найти платформу общего назначения, где бы не было int16_t. Даже если операции выполняются в 32- или 64-битном int, этот тип для хранения продолжает использоваться.

АТ>>>С и С++ широко используются не только на "платформах общего назначения".
N>>И сколько таких платформ осталось в реальном доступе и какая часть из них актуальна для текущего обсуждения?
АТ>Именно им текущее обсуждение и посвящено.

Что-то я такого не увидел. Упоминались Windows (32, 64 бита) и Linux (аналогично).
Если где-то нет int16_t, то это отсталость некоторых версий конкретного компилятора, исправленная (AFAIK) в последних изданиях.

АТ>Что касается фактической актуальности — это не имеет никакого значения. Как только такие платформы потеряют свою актуальность, их поддержка будет убрана из стандарта языка, как это произошло, например, с прямым и обратным кодами в представлении знаковых целых.


Ну давайте уточним у топикстартера, насколько ему актуальна какая-нибудь PDP-10 с 18-битным словом.

АТ>А пока нюансы, направленные на поддержку этих платформ, присутствуют в спецификации языка, никаких разглагольствований об их "актуальности" не будет. Все здесь, без единого исключения, незыблемо убеждены в безграничной важности и критической актуальности таких платформ.


"Отучаемся говорить за всех" (c).
Re: размер встроенных типов зависит от платформы
От: кт  
Дата: 30.01.22 18:22
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Почему встроенные типы зависят от платформы ?


Потому, что хорошего парня Кернигана "сбил с пути и с панталыку" некий Деннис Ритчи, постоянно твердивший "если тебе нужен PL/1, ты знаешь, где его взять". Т.е. не надо заново изобретать уже существующий язык. Но вот как раз размер данных в битах вполне можно было взять в Си из PL/1, где, например, нет никаких long и short, а есть fixed(7), fixed(15), fixed(31), fixed(63) и т.д. и нет проблемы переноса в этом смысле.
Re[4]: размер встроенных типов зависит от платформы
От: T4r4sB Россия  
Дата: 30.01.22 18:26
Оценка:
Здравствуйте, netch80, Вы писали:

N>Сейчас использование доменных целочисленных типов (диапазоном или набором значений) восстанавливают, но очень медленно, и легаси этому сильно мешает.


Не надо. Любая попытка в арифметику — и либо лови ассерты, либо засирай код кастами к i32.
Re[5]: размер встроенных типов зависит от платформы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.01.22 19:24
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, netch80, Вы писали:


N>>Сейчас использование доменных целочисленных типов (диапазоном или набором значений) восстанавливают, но очень медленно, и легаси этому сильно мешает.


TB>Не надо. Любая попытка в арифметику — и либо лови ассерты, либо засирай код кастами к i32.


Это в каком языке? (Rust?) И в какую именно арифметику? И почему i32? Его точно хватит?

Насколько я понял описание ситуации, оно как раз происходит из некорректного определения доменов. Например, если вы складываете два числа типа i8, результат тоже загоняется в i8. Но по-нормальному он должен быть i9. Это если не учитывать семантику конкретного типа. А если учитывать — то она должна определять допустимые действия (как в C можно вычитать два указателя, но нельзя складывать).
Это сложнее писать в коде, конечно, но потом легче искать ошибки.

Можно, конечно, всех проконвертить к чему-то широкому вроде i32, в нём проверять только его ограничения, а затем проверять уже по результату укладки в выходную переменную. Это то, ради чего, возможно, поддерживают integral promotions, и что делает, например, GNAT (полностью его логику не знаю, но в тестах увидел как раз это).
Re[6]: размер встроенных типов зависит от платформы
От: T4r4sB Россия  
Дата: 30.01.22 19:44
Оценка:
Здравствуйте, netch80, Вы писали:

N>Это в каком языке? (Rust?) И в какую именно арифметику? И почему i32? Его точно хватит?


i32 с высокой вероятностью хратит.

N>Насколько я понял описание ситуации, оно как раз происходит из некорректного определения доменов. Например, если вы складываете два числа типа i8, результат тоже загоняется в i8. Но по-нормальному он должен быть i9.


А, ну-ну. Такое тебе ни один язык ещё лет 20 не поддержит. В реальном мире i8+i8=i8. Со всем вытекающим из этого говном.

N>Можно, конечно, всех проконвертить к чему-то широкому вроде i32, в нём проверять только его ограничения, а затем проверять уже по результату укладки в выходную переменную.


Это единственный рабочий способ в реальном мире на текущий момент. А ещё лучше вообще не конвертить, а сразу работать только с более широким типом, а допустимый диапазон проверять непосредственно в месте, где нужен диапазон. Правда, хипстеры будут недовольны, что это работает не так, как их любимые "кхампайл-тхайм инварайанты" (которые на самом деле не работают), ну и хрен с ними.
Re: размер встроенных типов зависит от платформы
От: qqqqq  
Дата: 30.01.22 21:28
Оценка: :)
Вообще в стандартных C/C++ <stdint.h> и <stdint> есть uint8_t,uint16_t, и т.п. типы, размер которых определен.
Re[2]: размер встроенных типов зависит от платформы
От: AleksandrN Россия  
Дата: 30.01.22 21:55
Оценка:
Здравствуйте, кт, Вы писали:

кт>Потому, что хорошего парня Кернигана "сбил с пути и с панталыку" некий Деннис Ритчи, постоянно твердивший "если тебе нужен PL/1, ты знаешь, где его взять". Т.е. не надо заново изобретать уже существующий язык. Но вот как раз размер данных в битах вполне можно было взять в Си из PL/1, где, например, нет никаких long и short, а есть fixed(7), fixed(15), fixed(31), fixed(63) и т.д. и нет проблемы переноса в этом смысле.


Может так сделано для возможности переноса языка на другие платформы? В те времена 8-битный байт и целочисленные типы, в которых разрядность кратна 8, ещё не были стандартом де-факто. Например — в PDP-8 использовались 12-разрядные слова.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.