Получение другого размера заголовка путем изменения размера окна

Напомните, какую часть проблемы не решает следующая проблема ...

DROP TABLE IF EXISTS product;

CREATE TABLE product
(id SERIAL PRIMARY KEY
,title VARCHAR(30) NOT NULL
,pages INT NOT NULL
);

INSERT INTO product VALUES
(1,'Harry Potter',230),
(2,'Lord of the Rings',950),
(3,'Game of Thrones',980);

DROP TABLE IF EXISTS prices;

CREATE TABLE prices
(product_id INT NOT NULL
,book_type INT NOT NULL
,price DECIMAL(5,2) NOT NULL
,PRIMARY KEY(product_id,book_type)
);

INSERT INTO prices VALUES
(1,0,20.40),
(1,1,28.00),
(1,2,40.00),
(2,0,15.00),
(2,1,25.50),
(2,2,42.00),
(3,0,21.00),
(3,1,30.50),
(3,2,47.00);

SELECT c.*
     , a.*
  FROM prices a
  JOIN prices b
    ON b.product_id = a.product_id
  JOIN product c
    ON c.id = b.product_id
 WHERE b.price LIKE '%1%';
+----+-------------------+-------+------------+-----------+-------+
| id | title             | pages | product_id | book_type | price |
+----+-------------------+-------+------------+-----------+-------+
|  2 | Lord of the Rings |   950 |          2 |         0 | 15.00 |
|  2 | Lord of the Rings |   950 |          2 |         1 | 25.50 |
|  2 | Lord of the Rings |   950 |          2 |         2 | 42.00 |
|  3 | Game of Thrones   |   980 |          3 |         0 | 21.00 |
|  3 | Game of Thrones   |   980 |          3 |         1 | 30.50 |
|  3 | Game of Thrones   |   980 |          3 |         2 | 47.00 |
+----+-------------------+-------+------------+-----------+-------+
7
задан Coding Mash 7 September 2012 в 16:40
поделиться

9 ответов

Посмотрите этот вопрос: Почему sizeof для структуры не равен сумме sizeof каждого участника?.

Я полагаю, что компилятор понимает намек для отключения дополнения при использовании "неподписанного интервала wWindow:16" синтаксис.

Кроме того, обратите внимание, что короткими, как гарантируют, не составят 16 битов. Гарантия то, что: 16 битов <= размер короткого <= размер интервала.

2
ответ дан 6 December 2019 в 21:21
поделиться

Поскольку компилятор упаковывает Ваше битовое поле в 32-разрядный интервал, не 16-разрядный объект.

В целом необходимо избежать битовых полей и использовать другие явные константы (перечисления или безотносительно) с явным побитовым маскированием и смещающийся для доступа к 'подполям' в поле.

Вот одна причина, почему битовых полей нужно избежать - они не являются очень портативными между компиляторами даже для той же платформы. из стандарта C99 (существует подобная формулировка в стандарте C90):

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

Вы не можете гарантировать, 'охватит' ли немного поля международную границу или не, и Вы не можете указать, запускается ли битовое поле в низкопроизводительном из интервала или верхнем уровне интервала (это независимо от того, с обратным порядком байтов ли процессор или с прямым порядком байтов).

6
ответ дан 6 December 2019 в 21:21
поделиться

Компилятор дополняет участника структуры небитового поля к 32-разрядному - собственное выравнивание слов. Для фиксации этого сделайте пакет #pragma (0) перед структурой и пакетом #pragma () после.

0
ответ дан 6 December 2019 в 21:21
поделиться

Интересный - я думал бы, что "WORD" оценит к "короткому целому без знака", таким образом, у Вас была бы та проблема больше чем в одном месте.

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

0
ответ дан 6 December 2019 в 21:21
поделиться

Ваши серии "неподписанного int:xx" битовые поля израсходовали только 16 из 32 битов в интервале. Другие 16 битов (2 байта) там, но неиспользованный. Это сопровождается коротким целым без знака, которое находится на международной границе и затем WORD, который является вдоль выровненного на международной границе, что означает что там 2 байта дополнения между ними.

Когда Вы переключаетесь на "неподписанный интервал wWindow:16", вместо того, чтобы быть отдельным коротким, компилятор использует неиспользованные части предыдущего битового поля, таким образом, никакие отходы, нет короткие, и никакое дополнение после короткого, следовательно, Вы сохраняете четыре байта.

4
ответ дан 6 December 2019 в 21:21
поделиться

Не эксперт C/C++ когда дело доходит до упаковки. Но я предполагаю, что существует правило в спецификации, которая говорит, что, когда небитовое поле следует за битовым полем, оно должно быть выровненное на границе слова независимо от того, помещается ли оно в остающееся пространство. Путем создания этого явным битовый вектором Вы избегаете этой проблемы.

Снова это - предположение с легким опытом.

0
ответ дан 6 December 2019 в 21:21
поделиться

Границы структуры в памяти могут быть дополнены компилятором в зависимости от размера и порядка полей.

0
ответ дан 6 December 2019 в 21:21
поделиться

Я думаю, что Mike B разобрался в нем, но но не совершенно ясный. Когда Вы просите "короткий", это выровненное на границе на 32 бита. Когда Вы просите int:16, это не. Таким образом, int:16 соответствует прямо после th поля прибыли до уплаты налогов и процентов, в то время как короткие пропуски 2 байта и запускается в следующем 32-разрядном блоке.

Остальная часть, что он говорит, совершенно применима - битовое поле никогда не должно использоваться для кодирования внешне видимой структуры, потому что нет никакой гарантии относительно того, как они выделяются. В лучшем случае они принадлежат встроенных программ, где сохранение байта важно. И даже там, Вы не можете использовать их для на самом деле controly биты в портах с отображенной памятью.

0
ответ дан 6 December 2019 в 21:21
поделиться

Вы видите различные значения из-за компилятора, упаковывающего правила. Вы видите правила, характерные для Visual Studio здесь.

Когда у Вас есть структура, которая должна быть упакована (или придерживаться некоторых определенных требований выравнивания), необходимо использовать пакет #pragma () опция. Для Вашего кода можно использовать пакет #pragma (0), который выровняет все элементы структуры на границах байта. Можно затем использовать пакет #pragma () для сброса упаковки структуры к, он - состояние по умолчанию. Вы видите больше информации о прагме пакета здесь.

0
ответ дан 6 December 2019 в 21:21
поделиться