aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2020-12-22 19:21:41 -0700
committerMelody Horn <melody@boringcactus.com>2020-12-22 19:21:41 -0700
commit3acb75147668942c535fb34c6335a18c2ca7c5c9 (patch)
tree880a29f4f690da9536d0cde10dbdc4156a10e114
parent2a5e244c74c7f23d46dd4b636a5590e81119dcd7 (diff)
downloadspec-3acb75147668942c535fb34c6335a18c2ca7c5c9.tar.gz
spec-3acb75147668942c535fb34c6335a18c2ca7c5c9.zip
define fragile union
-rw-r--r--language/type-definition.rst24
1 files changed, 22 insertions, 2 deletions
diff --git a/language/type-definition.rst b/language/type-definition.rst
index 7b90934..04cc858 100644
--- a/language/type-definition.rst
+++ b/language/type-definition.rst
@@ -86,6 +86,26 @@ Defining Types
However, there is no internal indication of which type of data is actually being stored in the union.
As such, in non-trivial cases no compiler can predict which field is or is not valid, and any statement which reads a field of a fragile union must itself be a :crowbar:ref:`FragileStatement`.
- .. todo::
+ The size of a fragile union is the largest size of any of its members.
+ The address of each member is the address of the union object itself.
+ The member which was most recently set will retain its value.
+ Reading another member with size no larger than the most recently set member will interpret the first bytes of the most recently set member as a value of the type of the member being read.
+
+ For example, the functions ``test1`` and ``test2`` are equivalent::
+
+ fragile union Example {
+ float32 float_data;
+ uint32 uint_data;
+ }
- explain memory layout of fragile unions
+ uint32 test1(float32 arg) {
+ union Example temp;
+ temp.float_data = arg;
+ fragile return temp.uint_data;
+ }
+
+ uint32 test2(float32 arg) {
+ float32* temp = &arg;
+ fragile uint32* temp_casted = (uint32*)temp;
+ return *temp_casted;
+ }