diff options
author | Melody Horn <melody@boringcactus.com> | 2020-12-22 19:21:41 -0700 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2020-12-22 19:21:41 -0700 |
commit | 3acb75147668942c535fb34c6335a18c2ca7c5c9 (patch) | |
tree | 880a29f4f690da9536d0cde10dbdc4156a10e114 | |
parent | 2a5e244c74c7f23d46dd4b636a5590e81119dcd7 (diff) | |
download | spec-3acb75147668942c535fb34c6335a18c2ca7c5c9.tar.gz spec-3acb75147668942c535fb34c6335a18c2ca7c5c9.zip |
define fragile union
-rw-r--r-- | language/type-definition.rst | 24 |
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; + } |