Вы запускаете два разных потока, но они будут работать по-настоящему параллельно, если у вас есть хотя бы двухъядерная машина. Многопоточность Google Java.
Путаница заключается в том, что C явно разрешает пул через объединение, тогда как C ++ ( c ++ 11 ) не имеет такого разрешения.
6.5.2.3 Элементы структуры и объединения
95) Если элемент, используемый для чтения содержимого объекта объединения, не совпадает с элементом, который использовался последним сохранить значение в объекте, соответствующая часть представления объекта значения интерпретируется как представление объекта в новом типе, как описано в 6.2.6 (процесс, иногда называемый «type punning»). Это может быть ловушечное представление.
blockquote>Ситуация с C ++:
9.5. Unions [class.union]
В объединении не более одного нестатического элемента данных могут быть активны в любое время, то есть значение не более одного из нестатических члены данных могут быть сохранены в союзе в любое время.
blockquote>C ++ позже имеет язык, допускающий использование объединений, содержащих
struct
s с общими начальными последовательностями; это, однако, не позволяет печатать по типу.Чтобы определить, разрешен ли тип объединения в C ++, мы должны искать дальше. Напомним, что c99 является нормативной ссылкой для C ++ 11 (и C99 имеет схожий язык с C11, разрешающим объединение типа-punning):
3.9 Типы [basic.types ]
4 - Объектное представление объекта типа T является последовательностью N неподписанных объектов char, взятых объектом типа T, где N равно sizeof (T). Представление значения объекта представляет собой набор битов, которые содержат значение типа T. Для типов с тривиальной копией представление значений представляет собой набор бит в представлении объекта, который определяет значение, которое является одним дискретным элементом реализации, определенный набор значений. 42 42) Цель состоит в том, что модель памяти C ++ совместима с моделью языка программирования ISO / IEC 9899.
blockquote>Это особенно интересно, когда мы читаем
3.8 Время жизни объекта [basic.life]
Время жизни объекта типа T начинается, когда: - получено хранилище с правильным выравниванием и размером для типа T, и - если объект не имеет
blockquote>Итак, для примитивного типа (который ipso facto имеет тривиальную инициализацию), содержащегося в объединении, время жизни объекта охватывает, по крайней мере, время жизни самого союза. Это позволяет нам вызывать
3.9.2 Типы соединений [basic.compound]
Если объект типа T расположен по адресу A, указатель типа cv T *, значение которого является адресом A, указывается на этот объект, независимо от того, как было получено это значение.
blockquote>Предполагая, что операция, которую нас интересует, значение неактивного члена профсоюза и приведенное выше, что мы имеем действительную ссылку на объект, на который ссылается этот член, эта операция является преобразованием lvalue-to-rvalue:
4.1 Преобразование Lvalue-to-rvalue [conv.lval]
Значение gl для нефункционного типа без массива
blockquote>T
может быть преобразовано в prvalue. ЕслиT
является неполным типом, программа, которая требует этого преобразования, плохо сформирована. Если объект, к которому относится glvalue, не является объектом типаT
и не является объектом типа, полученного изT
, или если объект не инициализирован, программа, которая требует этого преобразования, имеет неопределенное поведение.Тогда возникает вопрос, инициализируется ли объект, который является неактивным членом профсоюза, хранилищем активному члену объединения. Насколько я могу судить, это не так, поэтому, если:
- объединение копируется в хранилище массива
char
и обратно (3.9: 2) или- объединение копируется в другое объединение одного и того же типа (3.9: 3) или
- соединение осуществляется через границы языка программным элементом, соответствующим ISO / IEC 9899 (поскольку (3.9: 4 примечание 42), затем
доступ к объединению неактивным членом определяется и определяется следующим образом представление объектов и значений, доступ без одного из указанных выше интерпозиций - это неопределенное поведение. Это имеет значение для оптимизаций, которые могут быть выполнены в такой программе, поскольку реализация может, конечно, предполагать, что неопределенное поведение не происходит.
То есть, хотя мы можем законно сформировать lvalue для не- активный член объединения (поэтому назначение неактивного элемента без построения в порядке) считается неинициализированным.
Стандарт C ++ 11 говорит об этом следующим образом
9.5 Unions
В объединении не более одного нестатического элемента данных могут быть активны при в любое время, то есть значение не более одного из нестатических элементов данных может быть сохранено в союзе в любое время.
blockquote>Если хранится только одно значение, как вы можете читать еще? Это просто не существует.
Документация gcc перечисляет это в . Определенное поведение реализации
- A член объекта union обращается с использованием члена другого типа (C90 6.3.2.3).
Соответствующие байты представления объекта рассматриваются как объект типа, используемого для доступа. См. «Тип-караун». Это может быть ловушечное представление.
blockquote>, указывающее, что это не требуется стандартом C.
2016-01-05: через комментарии я был связанный с Отчет о дефекте C99 № 283 , который добавляет аналогичный текст в виде сноски к стандартным документам C:
78a) Если элемент используется для доступа к содержимому union - это не то же самое, что последний элемент, используемый для хранения значения в объекте, соответствующая часть представления объекта значения интерпретируется как представление объекта в новом типе, как описано в 6.2.6 (процесс, иногда называемый «type punning»). Это может быть ловушечное представление.
blockquote>Не уверен, что он много разъясняет, учитывая, что сноска не является нормативной для стандарта.
Я думаю, что самый близкий стандарт приходит к утверждению, что неопределенное поведение - это то, где он определяет поведение для объединения, содержащего общую начальную последовательность (C99, §6.5.2.3 / 5):
Для упрощения использования профсоюзов существует одна специальная гарантия: если объединение содержит несколько структур, которые имеют общую начальную последовательность (см. Ниже), и если объект объединения в настоящее время содержит одну из этих структур, разрешается проверять общие начальная часть любого из них в любом месте, где видна декларация полного типа объединения. Две структуры имеют общую начальную последовательность, если соответствующие члены имеют совместимые типы (и для бит-полей, одинаковые ширины) для последовательности из одного или нескольких начальных элементов.
blockquote>C ++ 11 дает аналогичные требования / разрешения в §9.2 / 19:
Если объединение стандартного макета содержит две или более структуры стандартного макета, которые совместно используют общую начальную последовательность, и если объект объединения стандартного макета в настоящее время содержит одну из этих структур стандартной компоновки, разрешено проверять общую начальную часть любого из них. Две структуры стандартного компоновки имеют общую начальную последовательность, если соответствующие члены имеют совместимые с макетами типы, и ни один из них не является битовым полем, либо оба являются битовыми полями с одинаковой шириной для последовательности из одного или нескольких начальных элементов.
blockquote>Хотя ни один из них не является прямым, оба они имеют сильное значение, что «проверка» (чтение) члена «разрешена» только , если 1) она (часть) член, который недавно был написан, или 2) является частью общей исходной последовательности.
Это не прямой оператор, который делает иначе, это неопределенное поведение, но это самый близкий из которых я знаю.
union
не определено, так как у меня создалось впечатление от конкретного блога, что все в порядке, и построил вокруг него несколько крупных структур и проектов. Теперь я думаю i>, возможно, все в порядке, так как мои union
s содержат классы с одинаковыми типами на передней панели
– underscore_d
31 December 2015 в 14:55
union
содержит eg i> a uint8_t
и class Something { uint8_t myByte; [...] };
- я бы предположил, что это условие также применимо и здесь, но он сформулирован очень преднамеренно, чтобы разрешить только struct
s. К счастью, я уже использую эти вместо исходных примитивов: O
– underscore_d
31 December 2015 в 15:04
Я хорошо объясню это на примере. предположим, что мы имеем следующий союз:
union A{
int x;
short y[2];
};
Я полагаю, что sizeof(int)
дает 4, а sizeof(short)
дает 2. когда вы пишете union A a = {10}
, чтобы создать новый var типа A вставьте в него значение 10.
ваша память должна выглядеть так: (помните, что все члены союза получают одно и то же местоположение)
| x | | y[0] | y[1] | ----------------------------------------- a-> |0000 0000|0000 0000|0000 0000|0000 1010| -----------------------------------------
, как вы могли видеть, значение ax равно 10, значение ay 1 равно 10, а значение ay [0] равно 0.
теперь, что хорошо, если я это сделаю?
a.y[0] = 37;
наша память будет выглядеть так:
| x | | y[0] | y[1] | ----------------------------------------- a-> |0000 0000|0010 0101|0000 0000|0000 1010| -----------------------------------------
это превратит значение ax в 2424842 (в десятичном виде).
теперь, если ваш союз имеет float или double, ваша карта памяти будет скорее беспорядочной, потому что вы храните точные числа. более подробную информацию вы можете получить в здесь .
T
i>). – ecatmur 19 October 2012 в 09:05