91. Работайте с типами, а не с представлениями
91. Работайте с типами, а не с представлениями
Резюме
Не пытайтесь делать какие-то предположения о том, как именно объекты представлены в памяти. Как именно следует записывать и считывать объекты из памяти — пусть решают типы объектов.
Обсуждение
Стандарт С++ дает очень мало гарантий по поводу представления типов в памяти.
• Целые числа используют двоичное представление.
• Для отрицательных чисел используется дополнительный код числа в двоичной системе.
• Обычные старые типы (Plain Old Data, POD[5]) имеют совместимое с С размещение в памяти: переменные-члены хранятся в порядке их объявления.
• Тип int занимает как минимум 16 битов.
В частности, достаточно распространенные соглашения не гарантированы ни для всех имеющихся архитектур, ни тем более для архитектур, которые могут появиться в будущем. Так что не забывайте о следующем.
• Размер int не равен ни 32 битам, ни какому-либо иному фиксированному размеру.
• Указатели и целые числа не всегда имеют один и тот же размер и не могут свободно преобразовываться друг в друга.
• Размещение класса в памяти не всегда приводит к размещению базового класса и членов в указанном порядке.
• Между членами класса (даже если они являются POD) могут быть промежутки в целях выравнивания.
• offsetof работает только для POD, но не для всех классов (хотя компилятор может и не сообщать об ошибках).
• Класс может иметь скрытые поля.
• Указатели могут быть совсем не похожи на целые числа. Если два указателя упорядочены и вы можете преобразовать их в целые числа, то получающиеся значения могут быть упорядочены иначе.
• Нельзя переносимо полагаться на конкретное размещение автоматических переменных в памяти или на направление роста стека.
• Указатели на функции могут иметь размер, отличный от размера указателя void*, несмотря на то, что некоторые API заставляют вас предположить, что их размеры одинаковы.
• Из-за вопросов выравнивания вы не можете записывать ни один объект по произвольному адресу в памяти.
Просто корректно определите типы, а затем читайте и записывайте данные с использованием указанных типов вместо работы с отдельными битами, словами и адресами. Модель памяти С++ гарантирует эффективную работу, не заставляя вас при этом работать с представлениями данных в памяти. Так и не делайте этого.
Ссылки
[Dewhurst03] §95
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Синтаксис DDL для работы с представлениями
Синтаксис DDL для работы с представлениями Для создания и удаления представлений существуют команды, определенные DDL (Data Definition Language - подмножество SQL, см. глоссарий), которые мы сейчас рассмотрим.Чтобы создать представление в InterBase, необходимо использовать предложение
3.2. Работа с различными типами данных
3.2. Работа с различными типами данных Тип, определяемый пользователемVBA позволяет пользователю определять свои собственные типы данных. Определенный пользователем тип нужен, когда одной переменной необходимо обозначить несколько связанных по смыслу элементов данных,
Знакомство с пользовательскими типами данных
Знакомство с пользовательскими типами данных Пользовательский тип данных VBA представляет собой, так сказать, поселившуюся под одной крышей компанию выбранных вами типов данных. Определив пользовательский тип данных, вы получаете возможность объявлять переменные этого
3.6. Преобразования между числовыми типами
3.6. Преобразования между числовыми типами ПроблемаИмеется число одного типа и требуется преобразовать его в другой, как int в short или наоборот, но при этом необходимо перехватывать все ошибки переполнения (overflow) или потери значимости (underflow), возникающие при работе
Эксперименты с числовыми типами данных
Эксперименты с числовыми типами данных Числовые типы .NET поддерживают свойства MaxValue и МinValue, сообщающие информацию о диапазоне данных, которые может хранить данный тип. Предположим, что мы создали несколько переменных типа System.UInt16 (unsigned short – короткое целое без знака), как
Работа с типами StringWriter и StringReader
Работа с типами StringWriter и StringReader Используя типы StringWriter и StringReader, вы можете обращаться с текстовой информацией, как с потоком символов в памяти. Это может оказаться полезным тогда, когда необходимо добавить символьную информацию в соответствующий буфер. В следующем
Работа с типами Windows Forms
Работа с типами Windows Forms При построении приложения Windows Forms вы можете, при желании, создать весь соответствующий программный код вручную (например, в редакторе Блокнот или в редакторе TextPad), а затем отправить файлы *.cs компилятору командной строки C# с флагом /target:winexe.
Работа с типами Brush
Работа с типами Brush Типы, производные от System.Drawing.Brush, используются для заполнения имеющегося региона заданным цветом, узором или изображением. Сам класс Brush является абстрактным типом, поэтому он не позволяет создать соответствующий экземпляр непосредственно. Однако Brush
Операции с числовыми типами
Операции с числовыми типами * Операции сравнения. Используйте стандартные операторы отношений (=, <, >, >=, <=, <> или !=)[17].Возможны сравнения строк с использованием таких операторов SQL, как CONTAINING, STARTING WITH и LIKE. В данных операциях числа трактуются как строки. Более
Преобразования между типами дата/время и другими типами данных
Преобразования между типами дата/время и другими типами данных Любой символьный тип или выражение, чье содержание может быть выражено в правильном литерале даты, может быть преобразовано в соответствующий тип дата/время.Типы данных времени и даты не могут быть
Работайте с правильными клиентами
Работайте с правильными клиентами Найдите основной рынок для вашего приложения и сосредоточьтесь исключительно на немКлиент не всегда прав. Правда в том, что вам придется определять кто прав, а кто ошибается — в рамках вашего приложения. Хорошая новость в том, что
Подпрограммы для работы с перечислимыми типами
Подпрограммы для работы с перечислимыми типами procedure Inc(var i: integer); Увеличивает значение переменной i на 1 procedure Inc(var i: integer; n: integer); Увеличивает значение переменной i на n procedure Dec(var i: integer); Уменьшает значение переменной i на 1 procedure Dec(var i: integer; n: integer);
6.2.5. Работаем с различными типами данных в ячейках
6.2.5. Работаем с различными типами данных в ячейках Для выполнения задания нам понадобятся материалы разд. 5.2.4 и 5.2.6.ЗаданиеБассейн объемом 360 м3 был заполнен водой до нормы 1 апреля 2008 года. Выпускной клапан был не плотно закрыт, поэтому бассейн терял в день 30 м3