diff options
Diffstat (limited to 'development/c++.html')
-rw-r--r-- | development/c++.html | 188 |
1 files changed, 187 insertions, 1 deletions
diff --git a/development/c++.html b/development/c++.html index 94cc7fd..9e296dd 100644 --- a/development/c++.html +++ b/development/c++.html @@ -83,7 +83,7 @@ <nav id="sidebar" class="sidebar" aria-label="Table of contents"> <div class="sidebar-scrollbox"> - <ol class="chapter"><li class="chapter-item expanded affix "><a href="../intro.html">Introduction</a></li><li class="chapter-item expanded "><a href="../tools/index.html"><strong aria-hidden="true">1.</strong> Tools</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../tools/zsh.html"><strong aria-hidden="true">1.1.</strong> zsh</a></li><li class="chapter-item expanded "><a href="../tools/bash.html"><strong aria-hidden="true">1.2.</strong> bash</a></li><li class="chapter-item expanded "><a href="../tools/fish.html"><strong aria-hidden="true">1.3.</strong> fish</a></li><li class="chapter-item expanded "><a href="../tools/tmux.html"><strong aria-hidden="true">1.4.</strong> tmux</a></li><li class="chapter-item expanded "><a href="../tools/git.html"><strong aria-hidden="true">1.5.</strong> git</a></li><li class="chapter-item expanded "><a href="../tools/awk.html"><strong aria-hidden="true">1.6.</strong> awk</a></li><li class="chapter-item expanded "><a href="../tools/emacs.html"><strong aria-hidden="true">1.7.</strong> emacs</a></li><li class="chapter-item expanded "><a href="../tools/gpg.html"><strong aria-hidden="true">1.8.</strong> gpg</a></li><li class="chapter-item expanded "><a href="../tools/gdb.html"><strong aria-hidden="true">1.9.</strong> gdb</a></li><li class="chapter-item expanded "><a href="../tools/gdbserver.html"><strong aria-hidden="true">1.10.</strong> gdbserver</a></li><li class="chapter-item expanded "><a href="../tools/radare2.html"><strong aria-hidden="true">1.11.</strong> radare2</a></li><li class="chapter-item expanded "><a href="../tools/qemu.html"><strong aria-hidden="true">1.12.</strong> qemu</a></li><li class="chapter-item expanded "><a href="../tools/pacman.html"><strong aria-hidden="true">1.13.</strong> pacman</a></li><li class="chapter-item expanded "><a href="../tools/dot.html"><strong aria-hidden="true">1.14.</strong> dot</a></li></ol></li><li class="chapter-item expanded "><a href="../monitor/index.html"><strong aria-hidden="true">2.</strong> Resource analysis & monitor</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../monitor/lsof.html"><strong aria-hidden="true">2.1.</strong> lsof</a></li><li class="chapter-item expanded "><a href="../monitor/ss.html"><strong aria-hidden="true">2.2.</strong> ss</a></li><li class="chapter-item expanded "><a href="../monitor/pidstat.html"><strong aria-hidden="true">2.3.</strong> pidstat</a></li><li class="chapter-item expanded "><a href="../monitor/pgrep.html"><strong aria-hidden="true">2.4.</strong> pgrep</a></li><li class="chapter-item expanded "><a href="../monitor/pmap.html"><strong aria-hidden="true">2.5.</strong> pmap</a></li><li class="chapter-item expanded "><a href="../monitor/pstack.html"><strong aria-hidden="true">2.6.</strong> pstack</a></li></ol></li><li class="chapter-item expanded "><a href="../trace_profile/index.html"><strong aria-hidden="true">3.</strong> Trace and Profile</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../trace_profile/strace.html"><strong aria-hidden="true">3.1.</strong> strace</a></li><li class="chapter-item expanded "><a href="../trace_profile/ltrace.html"><strong aria-hidden="true">3.2.</strong> ltrace</a></li><li class="chapter-item expanded "><a href="../trace_profile/perf.html"><strong aria-hidden="true">3.3.</strong> perf</a></li><li class="chapter-item expanded "><a href="../trace_profile/oprofile.html"><strong aria-hidden="true">3.4.</strong> OProfile</a></li><li class="chapter-item expanded "><a href="../trace_profile/time.html"><strong aria-hidden="true">3.5.</strong> time</a></li></ol></li><li class="chapter-item expanded "><a href="../binary/index.html"><strong aria-hidden="true">4.</strong> Binary</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../binary/od.html"><strong aria-hidden="true">4.1.</strong> od</a></li><li class="chapter-item expanded "><a href="../binary/xxd.html"><strong aria-hidden="true">4.2.</strong> xxd</a></li><li class="chapter-item expanded "><a href="../binary/readelf.html"><strong aria-hidden="true">4.3.</strong> readelf</a></li><li class="chapter-item expanded "><a href="../binary/objdump.html"><strong aria-hidden="true">4.4.</strong> objdump</a></li><li class="chapter-item expanded "><a href="../binary/nm.html"><strong aria-hidden="true">4.5.</strong> nm</a></li></ol></li><li class="chapter-item expanded "><a href="../development/index.html"><strong aria-hidden="true">5.</strong> Development</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../development/c++filt.html"><strong aria-hidden="true">5.1.</strong> c++filt</a></li><li class="chapter-item expanded "><a href="../development/c++.html" class="active"><strong aria-hidden="true">5.2.</strong> c++</a></li><li class="chapter-item expanded "><a href="../development/glibc.html"><strong aria-hidden="true">5.3.</strong> glibc</a></li><li class="chapter-item expanded "><a href="../development/gcc.html"><strong aria-hidden="true">5.4.</strong> gcc</a></li><li class="chapter-item expanded "><a href="../development/make.html"><strong aria-hidden="true">5.5.</strong> make</a></li><li class="chapter-item expanded "><a href="../development/ld.so.html"><strong aria-hidden="true">5.6.</strong> ld.so</a></li><li class="chapter-item expanded "><a href="../development/symbolver.html"><strong aria-hidden="true">5.7.</strong> symbol versioning</a></li><li class="chapter-item expanded "><a href="../development/python.html"><strong aria-hidden="true">5.8.</strong> python</a></li><li class="chapter-item expanded "><a href="../development/gcov.html"><strong aria-hidden="true">5.9.</strong> gcov</a></li></ol></li><li class="chapter-item expanded "><a href="../linux/index.html"><strong aria-hidden="true">6.</strong> Linux</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../linux/systemd.html"><strong aria-hidden="true">6.1.</strong> systemd</a></li><li class="chapter-item expanded "><a href="../linux/coredump.html"><strong aria-hidden="true">6.2.</strong> coredump</a></li><li class="chapter-item expanded "><a href="../linux/ptrace_scope.html"><strong aria-hidden="true">6.3.</strong> ptrace_scope</a></li><li class="chapter-item expanded "><a href="../linux/cryptsetup.html"><strong aria-hidden="true">6.4.</strong> cryptsetup</a></li><li class="chapter-item expanded "><a href="../linux/swap.html"><strong aria-hidden="true">6.5.</strong> swap</a></li><li class="chapter-item expanded "><a href="../linux/input.html"><strong aria-hidden="true">6.6.</strong> input</a></li><li class="chapter-item expanded "><a href="../linux/acl.html"><strong aria-hidden="true">6.7.</strong> acl</a></li><li class="chapter-item expanded "><a href="../linux/zfs.html"><strong aria-hidden="true">6.8.</strong> zfs</a></li></ol></li><li class="chapter-item expanded "><a href="../network/index.html"><strong aria-hidden="true">7.</strong> Network</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../network/tcpdump.html"><strong aria-hidden="true">7.1.</strong> tcpdump</a></li><li class="chapter-item expanded "><a href="../network/firewall-cmd.html"><strong aria-hidden="true">7.2.</strong> firewall-cmd</a></li><li class="chapter-item expanded "><a href="../network/nftables.html"><strong aria-hidden="true">7.3.</strong> nftables</a></li></ol></li><li class="chapter-item expanded "><a href="../web/index.html"><strong aria-hidden="true">8.</strong> Web</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../web/html.html"><strong aria-hidden="true">8.1.</strong> html</a></li><li class="chapter-item expanded "><a href="../web/chartjs.html"><strong aria-hidden="true">8.2.</strong> chartjs</a></li></ol></li><li class="chapter-item expanded "><a href="../arch/index.html"><strong aria-hidden="true">9.</strong> Arch</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../arch/x86_64.html"><strong aria-hidden="true">9.1.</strong> x86_64</a></li><li class="chapter-item expanded "><a href="../arch/arm64.html"><strong aria-hidden="true">9.2.</strong> arm64</a></li><li class="chapter-item expanded "><a href="../arch/armv7.html"><strong aria-hidden="true">9.3.</strong> armv7</a></li><li class="chapter-item expanded "><a href="../arch/riscv.html"><strong aria-hidden="true">9.4.</strong> riscv</a></li></ol></li></ol> + <ol class="chapter"><li class="chapter-item expanded affix "><a href="../intro.html">Introduction</a></li><li class="chapter-item expanded "><a href="../tools/index.html"><strong aria-hidden="true">1.</strong> Tools</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../tools/zsh.html"><strong aria-hidden="true">1.1.</strong> zsh</a></li><li class="chapter-item expanded "><a href="../tools/bash.html"><strong aria-hidden="true">1.2.</strong> bash</a></li><li class="chapter-item expanded "><a href="../tools/fish.html"><strong aria-hidden="true">1.3.</strong> fish</a></li><li class="chapter-item expanded "><a href="../tools/tmux.html"><strong aria-hidden="true">1.4.</strong> tmux</a></li><li class="chapter-item expanded "><a href="../tools/git.html"><strong aria-hidden="true">1.5.</strong> git</a></li><li class="chapter-item expanded "><a href="../tools/awk.html"><strong aria-hidden="true">1.6.</strong> awk</a></li><li class="chapter-item expanded "><a href="../tools/emacs.html"><strong aria-hidden="true">1.7.</strong> emacs</a></li><li class="chapter-item expanded "><a href="../tools/gpg.html"><strong aria-hidden="true">1.8.</strong> gpg</a></li><li class="chapter-item expanded "><a href="../tools/gdb.html"><strong aria-hidden="true">1.9.</strong> gdb</a></li><li class="chapter-item expanded "><a href="../tools/gdbserver.html"><strong aria-hidden="true">1.10.</strong> gdbserver</a></li><li class="chapter-item expanded "><a href="../tools/radare2.html"><strong aria-hidden="true">1.11.</strong> radare2</a></li><li class="chapter-item expanded "><a href="../tools/qemu.html"><strong aria-hidden="true">1.12.</strong> qemu</a></li><li class="chapter-item expanded "><a href="../tools/pacman.html"><strong aria-hidden="true">1.13.</strong> pacman</a></li><li class="chapter-item expanded "><a href="../tools/dot.html"><strong aria-hidden="true">1.14.</strong> dot</a></li></ol></li><li class="chapter-item expanded "><a href="../monitor/index.html"><strong aria-hidden="true">2.</strong> Resource analysis & monitor</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../monitor/lsof.html"><strong aria-hidden="true">2.1.</strong> lsof</a></li><li class="chapter-item expanded "><a href="../monitor/ss.html"><strong aria-hidden="true">2.2.</strong> ss</a></li><li class="chapter-item expanded "><a href="../monitor/pidstat.html"><strong aria-hidden="true">2.3.</strong> pidstat</a></li><li class="chapter-item expanded "><a href="../monitor/pgrep.html"><strong aria-hidden="true">2.4.</strong> pgrep</a></li><li class="chapter-item expanded "><a href="../monitor/pmap.html"><strong aria-hidden="true">2.5.</strong> pmap</a></li><li class="chapter-item expanded "><a href="../monitor/pstack.html"><strong aria-hidden="true">2.6.</strong> pstack</a></li></ol></li><li class="chapter-item expanded "><a href="../trace_profile/index.html"><strong aria-hidden="true">3.</strong> Trace and Profile</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../trace_profile/strace.html"><strong aria-hidden="true">3.1.</strong> strace</a></li><li class="chapter-item expanded "><a href="../trace_profile/ltrace.html"><strong aria-hidden="true">3.2.</strong> ltrace</a></li><li class="chapter-item expanded "><a href="../trace_profile/perf.html"><strong aria-hidden="true">3.3.</strong> perf</a></li><li class="chapter-item expanded "><a href="../trace_profile/oprofile.html"><strong aria-hidden="true">3.4.</strong> OProfile</a></li><li class="chapter-item expanded "><a href="../trace_profile/time.html"><strong aria-hidden="true">3.5.</strong> time</a></li></ol></li><li class="chapter-item expanded "><a href="../binary/index.html"><strong aria-hidden="true">4.</strong> Binary</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../binary/od.html"><strong aria-hidden="true">4.1.</strong> od</a></li><li class="chapter-item expanded "><a href="../binary/xxd.html"><strong aria-hidden="true">4.2.</strong> xxd</a></li><li class="chapter-item expanded "><a href="../binary/readelf.html"><strong aria-hidden="true">4.3.</strong> readelf</a></li><li class="chapter-item expanded "><a href="../binary/objdump.html"><strong aria-hidden="true">4.4.</strong> objdump</a></li><li class="chapter-item expanded "><a href="../binary/nm.html"><strong aria-hidden="true">4.5.</strong> nm</a></li></ol></li><li class="chapter-item expanded "><a href="../development/index.html"><strong aria-hidden="true">5.</strong> Development</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../development/c++filt.html"><strong aria-hidden="true">5.1.</strong> c++filt</a></li><li class="chapter-item expanded "><a href="../development/c++.html" class="active"><strong aria-hidden="true">5.2.</strong> c++</a></li><li class="chapter-item expanded "><a href="../development/glibc.html"><strong aria-hidden="true">5.3.</strong> glibc</a></li><li class="chapter-item expanded "><a href="../development/gcc.html"><strong aria-hidden="true">5.4.</strong> gcc</a></li><li class="chapter-item expanded "><a href="../development/make.html"><strong aria-hidden="true">5.5.</strong> make</a></li><li class="chapter-item expanded "><a href="../development/ld.so.html"><strong aria-hidden="true">5.6.</strong> ld.so</a></li><li class="chapter-item expanded "><a href="../development/symbolver.html"><strong aria-hidden="true">5.7.</strong> symbol versioning</a></li><li class="chapter-item expanded "><a href="../development/python.html"><strong aria-hidden="true">5.8.</strong> python</a></li><li class="chapter-item expanded "><a href="../development/gcov.html"><strong aria-hidden="true">5.9.</strong> gcov</a></li><li class="chapter-item expanded "><a href="../development/pgo.html"><strong aria-hidden="true">5.10.</strong> pgo</a></li></ol></li><li class="chapter-item expanded "><a href="../linux/index.html"><strong aria-hidden="true">6.</strong> Linux</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../linux/systemd.html"><strong aria-hidden="true">6.1.</strong> systemd</a></li><li class="chapter-item expanded "><a href="../linux/coredump.html"><strong aria-hidden="true">6.2.</strong> coredump</a></li><li class="chapter-item expanded "><a href="../linux/ptrace_scope.html"><strong aria-hidden="true">6.3.</strong> ptrace_scope</a></li><li class="chapter-item expanded "><a href="../linux/cryptsetup.html"><strong aria-hidden="true">6.4.</strong> cryptsetup</a></li><li class="chapter-item expanded "><a href="../linux/swap.html"><strong aria-hidden="true">6.5.</strong> swap</a></li><li class="chapter-item expanded "><a href="../linux/input.html"><strong aria-hidden="true">6.6.</strong> input</a></li><li class="chapter-item expanded "><a href="../linux/acl.html"><strong aria-hidden="true">6.7.</strong> acl</a></li><li class="chapter-item expanded "><a href="../linux/zfs.html"><strong aria-hidden="true">6.8.</strong> zfs</a></li></ol></li><li class="chapter-item expanded "><a href="../network/index.html"><strong aria-hidden="true">7.</strong> Network</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../network/tcpdump.html"><strong aria-hidden="true">7.1.</strong> tcpdump</a></li><li class="chapter-item expanded "><a href="../network/firewall-cmd.html"><strong aria-hidden="true">7.2.</strong> firewall-cmd</a></li><li class="chapter-item expanded "><a href="../network/nftables.html"><strong aria-hidden="true">7.3.</strong> nftables</a></li></ol></li><li class="chapter-item expanded "><a href="../web/index.html"><strong aria-hidden="true">8.</strong> Web</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../web/html.html"><strong aria-hidden="true">8.1.</strong> html</a></li><li class="chapter-item expanded "><a href="../web/chartjs.html"><strong aria-hidden="true">8.2.</strong> chartjs</a></li></ol></li><li class="chapter-item expanded "><a href="../arch/index.html"><strong aria-hidden="true">9.</strong> Arch</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../arch/x86_64.html"><strong aria-hidden="true">9.1.</strong> x86_64</a></li><li class="chapter-item expanded "><a href="../arch/arm64.html"><strong aria-hidden="true">9.2.</strong> arm64</a></li><li class="chapter-item expanded "><a href="../arch/armv7.html"><strong aria-hidden="true">9.3.</strong> armv7</a></li><li class="chapter-item expanded "><a href="../arch/riscv.html"><strong aria-hidden="true">9.4.</strong> riscv</a></li></ol></li></ol> </div> <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div> </nav> @@ -170,6 +170,7 @@ <div id="content" class="content"> <main> <h1 id="c"><a class="header" href="#c">c++</a></h1> +<p>openstd <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/standards">cpp standards</a>.</p> <p>Source files of most examples is available <a href="https://github.com/johannst/notes/tree/master/src/development/c%2B%2B">here</a>.</p> <h2 id="type-deduction"><a class="header" href="#type-deduction">Type deduction</a></h2> <p>Force compile error to see what <code>auto</code> is deduced to.</p> @@ -178,6 +179,191 @@ // force compile error typename decltype(foo)::_; </code></pre> +<h2 id="strict-aliasing-and-type-punning"><a class="header" href="#strict-aliasing-and-type-punning">Strict aliasing and type punning</a></h2> +<p>The <code>strict aliasing</code> rules describe via which <code>alias</code> a value can be accessed.</p> +<blockquote> +<p>Informal: an <code>alias</code> is a reference / pointer to a value.</p> +</blockquote> +<p>Accessing a value through an alias that violates the strict aliasing rules is +<code>undefined behavior (UB)</code>.</p> +<p>Examples below on <a href="https://godbolt.org/z/TsvTY9zfj">godbolt</a>.</p> +<pre><code class="language-cpp">int i = 0; + +// Valid aliasing (signed / unsigned type). +*reinterpret_cast<signed int*>(&i); +*reinterpret_cast<unsigned int*>(&i); + +// Valid aliasing (cv qualified type). +*reinterpret_cast<const int*>(&i); +*reinterpret_cast<const unsigned*>(&i); + +// Valid aliasing (byte type). +*reinterpret_cast<char*>(&i); +*reinterpret_cast<std::byte*>(&i); + +// Invalid aliasing, dereferencing pointer is UB. +*reinterpret_cast<short*>(&i); +*reinterpret_cast<float*>(&i); +</code></pre> +<blockquote> +<p>NOTE: Casting pointer to invalid aliasing type is not directly UB, but +dereferencing the pointer is UB.</p> +</blockquote> +<pre><code class="language-cpp">short s[2] = { 1, 2 }; + +// Invalid aliasing (UB) - type punning, UB to deref ptr (int has stricter +// alignment requirements than short). +*reinterpret_cast<int*>(s); + + +// Arbitrary byte pointer. +char c[4] = { 1, 2, 3, 4 }; + +// Invalid aliasing (UB) - type punning, UB to deref ptr (int has stricter +// alignment requirements than char). +*reinterpret_cast<int*>(c); +</code></pre> +<p>At the time of writing, the current <a href="http://eel.is/c++draft/basic.lval#11">c++ std draft</a> +contains the following.</p> +<pre><code class="language-text">If a program attempts to access the stored value of an object through a glvalue +whose type is not **similar** (7.3.6) to one of the following types the +behavior is undefined [44] + +(11.1) the dynamic type of the object, +(11.2) a type that is the signed or unsigned type corresponding to the dynamic + type of the object, or +(11.3) a char, unsigned char, or std::byte type. + +[44]: The intent of this list is to specify those circumstances in which an + object can or cannot be aliased. +</code></pre> +<p>The paragraph is short but one also needs to understand the meaning of +<a href="http://eel.is/c++draft/conv.qual#def:similar_types">similar (<em>similar_types</em>)</a>.</p> +<p>This paragraph is actually somewhat more explicit in the <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf">c++17 std</a>.</p> +<pre><code class="language-text">If a program attempts to access the stored value of an object through a glvalue +of other than one of the following types the behavior is undefined [63] + +(11.1) the dynamic type of the object, +(11.2) a cv-qualified version of the dynamic type of the object, +(11.3) a type similar (as defined in 7.5) to the dynamic type of the object, +(11.4) a type that is the signed or unsigned type corresponding to the dynamic + type of the object, +(11.5) a type that is the signed or unsigned type corresponding to a + cv-qualified version of the dynamic type of the object, +(11.6) an aggregate or union type that includes one of the aforementioned types + among its elements or non- static data members (including, recursively, + an element or non-static data member of a subaggregate or contained + union), +(11.7) a type that is a (possibly cv-qualified) base class type of the dynamic + type of the object, +(11.8) a char, unsigned char, or std::byte type. + +[63]: The intent of this list is to specify those circumstances in which an + object may or may not be aliased. +</code></pre> +<p>Additional references:</p> +<ul> +<li> +<p><a href="https://gist.github.com/shafik/848ae25ee209f698763cffee272a58f8">What is the Strict Aliasing Rule and Why do we care</a></p> +<p>The article shows a small example how the compiler may optimized using the +strict aliasing rules.</p> +<pre><code class="language-cpp">int alias(int* i, char* c) { + *i = 1; + *c = 'a'; // char* may alias int* + return *i; +} + +int noalias(int* i, short* s) { + *i = 1; + *s = 2; // short* does not alias int* + return *i; +} +</code></pre> +<pre><code class="language-x86asm">alias(int*, char*): +mov DWORD PTR [rdi] ,0x1 ; *i = 1; +mov BYTE PTR [rsi], 0x61 ; *c = 'a'; +mov eax,DWORD PTR [rdi] ; Must reload, char* can alias int*. +ret + +noalias(int*, short*): +mov DWORD PTR [rdi], 0x1 ; *i = 1; +mov WORD PTR [rsi], 0x2 ; *s = 2; +mov eax,0x1 ; Must not reload, short* can not alias int*. +ret +</code></pre> +</li> +<li> +<p><a href="https://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing">reinterpret_cast</a> type aliasing</p> +<blockquote> +<ol start="5"> +<li>Any object pointer type <code>T1*</code> can be converted to another object pointer +type <code>cv T2*</code>. This is exactly equivalent to <code>static_cast<cv T2*>(static_cast<cv void*>(expression))</code> (which implies that if T2's +alignment requirement is not stricter than T1's, the value of the pointer +does not change and conversion of the resulting pointer back to its +original type yields the original value). In any case, the resulting +pointer may only be dereferenced safely if allowed by the type aliasing +rules (see below).</li> +</ol> +</blockquote> +<pre><code class="language-cpp">int I; +char* X = reinterpret_cast<char*>(&I); // Valid, char allowed to alias int. +*X = 42; +int* Y = reinterpret_cast<int*>(X); // Cast back to original type. +*Y = 1337; // safe + +char C[4]; +int* P = reinterpret_cast<int*>(C); // Cast is ok, not yet UB. +*P = 1337; // UB, violates strict aliasing / alignment rules. + // https://stackoverflow.com/questions/52492229/c-byte-array-to-int +</code></pre> +</li> +<li> +<p>On <code>gcc</code> strict aliasing is enabled starting with <code>-O2</code>.</p> +<pre><code class="language-bash">for i in {0..3} g s; do echo "-O$i $(g++ -Q --help=optimizers -O$i | grep fstrict-aliasing)"; done +-O0 -fstrict-aliasing [disabled] +-O1 -fstrict-aliasing [disabled] +-O2 -fstrict-aliasing [enabled] +-O3 -fstrict-aliasing [enabled] +-Og -fstrict-aliasing [disabled] +-Os -fstrict-aliasing [enabled] +</code></pre> +</li> +</ul> +<h3 id="__restrict-keyword"><a class="header" href="#__restrict-keyword"><code>__restrict</code> keyword</a></h3> +<p>The <code>__restrict</code> keyword allows the programmer to tell the compiler that two +pointer will not alias each other.</p> +<pre><code class="language-cpp">int alias(int* a, int* b) { + *a = 1; + *b = 2; + return *a; +} + +// alias(int*, int*): # @alias(int*, int*) +// mov dword ptr [rdi], 1 +// mov dword ptr [rsi], 2 +// mov eax, dword ptr [rdi] +// ret + +int noalias(int* __restrict a, int* __restrict b) { + *a = 1; + *b = 2; + return *a; +} + +// noalias(int*, int*): # @noalias(int*, int*) +// mov dword ptr [rdi], 1 +// mov dword ptr [rsi], 2 +// mov eax, 1 +// ret +</code></pre> +<p>However this should only be used with care and in a narrow scope, as it is easy +to violate self defined contract, see <a href="https://godbolt.org/z/e8x1af3Mh">godbolt</a>.</p> +<h3 id="type-punning"><a class="header" href="#type-punning">Type punning</a></h3> +<p>The correct way to do <code>type-punning</code> in c++:</p> +<ol> +<li><a href="https://en.cppreference.com/w/cpp/numeric/bit_cast"><code>std::bit_cast</code></a> (c++20)</li> +<li><a href="https://godbolt.org/z/3PM4jGvEz"><code>std::memcpy</code></a></li> +</ol> <h2 id="variadic-templates-parameter-pack"><a class="header" href="#variadic-templates-parameter-pack">Variadic templates (<a href="https://en.cppreference.com/w/cpp/language/parameter_pack">parameter pack</a>)</a></h2> <pre><code class="language-cpp">#include <iostream> |