aboutsummaryrefslogtreecommitdiffhomepage
path: root/development
diff options
context:
space:
mode:
Diffstat (limited to 'development')
-rw-r--r--development/c++.html82
-rw-r--r--development/cmake.html2
-rw-r--r--development/gcc.html6
-rw-r--r--development/gcov.html8
-rw-r--r--development/ld.so.html4
-rw-r--r--development/make.html12
-rw-r--r--development/pgo.html6
-rw-r--r--development/python.html24
-rw-r--r--development/symbolver.html44
9 files changed, 94 insertions, 94 deletions
diff --git a/development/c++.html b/development/c++.html
index c33016b..0d95860 100644
--- a/development/c++.html
+++ b/development/c++.html
@@ -326,7 +326,7 @@ int* P = reinterpret_cast<int*>(C); // Cast is ok, not yet UB.
</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 &quot;-O$i $(g++ -Q --help=optimizers -O$i | grep fstrict-aliasing)&quot;; done
+<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]
@@ -379,13 +379,13 @@ to violate self defined contract, see <a href="https://godbolt.org/z/e8x1af3Mh">
// Base case with one parameter.
template&lt;int P&gt;
void show_int() {
- printf(&quot;%d\n&quot;, P);
+ printf("%d\n", P);
}
// General case with at least two parameters, to disambiguate from base case.
template&lt;int P0, int P1, int... Params&gt;
void show_int() {
- printf(&quot;%d, &quot;, P0);
+ printf("%d, ", P0);
show_int&lt;P1, Params...&gt;();
}
@@ -400,13 +400,13 @@ void show(const T&amp; t) {
// General case with at least two parameters, to disambiguate from base case.
template&lt;typename T0, typename T1, typename... Types&gt;
void show(const T0&amp; t0, const T1&amp; t1, const Types&amp;... types) {
- std::cout &lt;&lt; t0 &lt;&lt; &quot;, &quot;;
+ std::cout &lt;&lt; t0 &lt;&lt; ", ";
show(t1, types...);
}
int main() {
show_int&lt;1, 2, 3, 4, 5&gt;();
- show(1, 1.0, &quot;foo&quot;, 'a');
+ show(1, 1.0, "foo", 'a');
}
</code></pre>
<h2 id="forwarding-reference-fwd-ref"><a class="header" href="#forwarding-reference-fwd-ref">Forwarding reference (<a href="https://en.cppreference.com/w/cpp/language/reference#Forwarding_references">fwd ref</a>)</a></h2>
@@ -456,21 +456,21 @@ void fwd_wrapper(T&amp;&amp; param) { // forwarding reference
int main() {
{
- std::puts(&quot;==&gt; wrapper rvalue reference&quot;);
+ std::puts("==&gt; wrapper rvalue reference");
wrapper(M{});
// calls use(M&amp;).
- std::puts(&quot;==&gt; wrapper lvalue reference&quot;);
+ std::puts("==&gt; wrapper lvalue reference");
struct M m;
wrapper(m);
// calls use(M&amp;).
}
{
- std::puts(&quot;==&gt; fwd_wrapper rvalue reference&quot;);
+ std::puts("==&gt; fwd_wrapper rvalue reference");
fwd_wrapper(M{});
// calls use(M&amp;&amp;).
- std::puts(&quot;==&gt; fwd_wrapper lvalue reference&quot;);
+ std::puts("==&gt; fwd_wrapper lvalue reference");
struct M m;
fwd_wrapper(m);
// calls use(M&amp;).
@@ -496,8 +496,8 @@ struct any_of&lt;T, U0, U...&gt; : any_of&lt;T, U...&gt; {};
template&lt;typename T, typename... U&gt;
constexpr bool any_of_v = any_of&lt;T, U...&gt;::value;
-static_assert(any_of_v&lt;int, char, bool, int&gt;, &quot;&quot;);
-static_assert(!any_of_v&lt;int, char, bool, float&gt;, &quot;&quot;);
+static_assert(any_of_v&lt;int, char, bool, int&gt;, "");
+static_assert(!any_of_v&lt;int, char, bool, float&gt;, "");
</code></pre>
<h2 id="example-sfinae-enable_if"><a class="header" href="#example-sfinae-enable_if">Example: <a href="https://en.cppreference.com/w/cpp/language/sfinae">SFINAE</a> (<a href="https://en.cppreference.com/w/cpp/types/enable_if">enable_if</a>)</a></h2>
<p>Provide a single entry point <code>Invoke</code> to call some <code>Operations</code>.
@@ -543,16 +543,16 @@ namespace impl {
template&lt;typename Ctx, template&lt;typename&gt; class Op, typename... P,
enable_if_bool&lt;has_dst&lt;Op&lt;Ctx&gt;&gt;&gt; = true&gt;
void Invoke(const Ctx&amp; C, P... params) {
- std::cout &lt;&lt; &quot;Invoke &quot; &lt;&lt; Op&lt;Ctx&gt;::Name &lt;&lt; '\n';
+ std::cout &lt;&lt; "Invoke " &lt;&lt; Op&lt;Ctx&gt;::Name &lt;&lt; '\n';
typename Op&lt;Ctx&gt;::Return R = impl::Invoke&lt;Ctx, Op&gt;(C, params...);
- std::cout &lt;&lt; &quot;returned -&gt; &quot; &lt;&lt; R &lt;&lt; '\n';
+ std::cout &lt;&lt; "returned -&gt; " &lt;&lt; R &lt;&lt; '\n';
}
// Invoke an OPERATION which has *NOT* a DESTINATION with arbitrary number of arguments.
template&lt;typename Ctx, template&lt;typename&gt; class Op, typename... P,
disable_if_bool&lt;has_dst&lt;Op&lt;Ctx&gt;&gt;&gt; = true&gt;
void Invoke(const Ctx&amp; C, P... params) {
- std::cout &lt;&lt; &quot;Invoke &quot; &lt;&lt; Op&lt;Ctx&gt;::Name &lt;&lt; &quot; without destination.&quot; &lt;&lt; '\n';
+ std::cout &lt;&lt; "Invoke " &lt;&lt; Op&lt;Ctx&gt;::Name &lt;&lt; " without destination." &lt;&lt; '\n';
impl::Invoke&lt;Ctx, Op&gt;(C, params...);
}
@@ -560,7 +560,7 @@ void Invoke(const Ctx&amp; C, P... params) {
struct Ctx {
void out(const char* s, unsigned v) const {
- printf(&quot;%s%x\n&quot;, s, v);
+ printf("%s%x\n", s, v);
}
};
@@ -570,7 +570,7 @@ template&lt;typename Ctx&gt;
struct OpA {
using HasCtx = std::false_type;
using Return = int;
- static constexpr const char* const Name = &quot;OpA&quot;;
+ static constexpr const char* const Name = "OpA";
constexpr Return operator()(int a, int b) const {
return a + b;
@@ -581,10 +581,10 @@ template&lt;typename Ctx&gt;
struct OpB {
using HasCtx = std::true_type;
using Return = void;
- static constexpr const char* const Name = &quot;OpB&quot;;
+ static constexpr const char* const Name = "OpB";
Return operator()(const Ctx&amp; C, unsigned a) const {
- C.out(&quot;a = &quot;, a);
+ C.out("a = ", a);
}
};
@@ -650,7 +650,7 @@ struct registry {
const auto it = m_fns.find(nm);
if (it == m_fns.end()) {
static_assert(std::is_default_constructible_v&lt;RET&gt;,
- &quot;RET must be default constructible&quot;);
+ "RET must be default constructible");
return {};
}
return std::invoke(it-&gt;second, p...);
@@ -661,7 +661,7 @@ struct registry {
static bool regfn_##REGISTRY##NAME() { \
const bool r = REGISTRY::get().add(#NAME, NAME); \
if (!r) { \
- std::puts(&quot;Failed to register test &quot; #NAME &quot;, same name already registered!&quot;); \
+ std::puts("Failed to register test " #NAME ", same name already registered!"); \
std::abort(); \
} \
return r; \
@@ -677,10 +677,10 @@ struct registry {
using REG1 = registry&lt;void&gt;;
TEST(REG1, test1) {
- std::puts(&quot;REG1::test1&quot;);
+ std::puts("REG1::test1");
}
TEST(REG1, test2) {
- std::puts(&quot;REG1::test2&quot;);
+ std::puts("REG1::test2");
}
// -- Usage 2 with convenience macro wrapper.
@@ -689,18 +689,18 @@ using REG2 = registry&lt;void, bool&gt;;
#define TEST2(NAME, ...) TEST(REG2, NAME, ##__VA_ARGS__)
TEST2(test1, bool val) {
- printf(&quot;REG2::test1 val %d\n&quot;, val);
+ printf("REG2::test1 val %d\n", val);
}
int main() {
const auto&amp; R1 = REG1::get();
R1.dump();
- R1.invoke(&quot;test1&quot;);
- R1.invoke(&quot;test2&quot;);
+ R1.invoke("test1");
+ R1.invoke("test2");
const auto&amp; R2 = REG2::get();
R2.dump();
- R2.invoke(&quot;test1&quot;, true);
+ R2.invoke("test1", true);
return 0;
}
@@ -757,7 +757,7 @@ struct Entry {
};
int main() {
- static_assert(is_entry_v&lt;Entry&lt;bool&gt;&gt;, &quot;&quot;);
+ static_assert(is_entry_v&lt;Entry&lt;bool&gt;&gt;, "");
}
</code></pre>
<p>The main mechanic can be explained with the following reduced example. If one
@@ -781,7 +781,7 @@ struct A {
struct B {};
-static_assert(is_valid&lt;A&gt;::value, &quot;is true&quot;);
+static_assert(is_valid&lt;A&gt;::value, "is true");
// * Compare template arg list with primary template, we only supplied one
// arg, the second one will be defaulted as
// is_valid&lt;A, void&gt;
@@ -795,7 +795,7 @@ static_assert(is_valid&lt;A&gt;::value, &quot;is true&quot;);
// * Specialization (2) matches &lt;A, void&gt;
// * Pick the most specialized version -&gt; (2)
-static_assert(!is_valid&lt;B&gt;::value, &quot;is false&quot;);
+static_assert(!is_valid&lt;B&gt;::value, "is false");
// * Compare template arg list with primary template, we only supplied one
// arg, the second one will be defaulted as
// is_valid&lt;A, void&gt;
@@ -846,7 +846,7 @@ struct pair&lt;int, int&gt; {
};
int main() {
- static_assert(pair&lt;int&gt;::kind == kIntBool, &quot;&quot;);
+ static_assert(pair&lt;int&gt;::kind == kIntBool, "");
// * Compare template arg list with primary template, we only supplied one
// arg, the second one will be defaulted as
// pair&lt;int, bool&gt;
@@ -858,7 +858,7 @@ int main() {
// * (4) &lt;int, bool&gt; pattern does not match
// * Pick the most specialized version -&gt; (3)
- static_assert(pair&lt;char, char&gt;::kind == kTT, &quot;&quot;);
+ static_assert(pair&lt;char, char&gt;::kind == kTT, "");
// * Compare template arg list against available specializations, this will
// try to match the pattern &lt;char, char&gt; against the patterns defined in the
// partial specializations.
@@ -867,7 +867,7 @@ int main() {
// * (4) &lt;char, char&gt; pattern does not match
// * Pick the most specialized version -&gt; (2)
- static_assert(pair&lt;int, int&gt;::kind == kIntInt, &quot;&quot;);
+ static_assert(pair&lt;int, int&gt;::kind == kIntInt, "");
// * Compare template arg list against available specializations, this will
// try to match the pattern &lt;int, int&gt; against the patterns defined in the
// partial specializations.
@@ -876,7 +876,7 @@ int main() {
// * (4) &lt;int, int&gt; pattern does not match
// * Pick the most specialized version -&gt; (3)
- static_assert(pair&lt;char, short&gt;::kind == kPrimary, &quot;&quot;);
+ static_assert(pair&lt;char, short&gt;::kind == kPrimary, "");
// * Compare template arg list against available specializations, this will
// try to match the pattern &lt;char, short&gt; against the patterns defined in the
// partial specializations.
@@ -897,25 +897,25 @@ struct S {};
struct M {
M() {
- std::puts(&quot;M()&quot;);
+ std::puts("M()");
}
M(const M&amp;) {
- std::puts(&quot;M(M&amp;)&quot;);
+ std::puts("M(M&amp;)");
}
M(M&amp;&amp;) {
- std::puts(&quot;M(M&amp;&amp;)&quot;);
+ std::puts("M(M&amp;&amp;)");
}
M&amp; operator=(const M&amp;) = delete;
M&amp; operator=(M&amp;&amp;) = delete;
M(S&amp;, int) {
- std::puts(&quot;M(S&amp;)&quot;);
+ std::puts("M(S&amp;)");
}
M(S&amp;&amp;, int) {
- std::puts(&quot;M(S&amp;&amp;)&quot;);
+ std::puts("M(S&amp;&amp;)");
}
~M() {
- std::puts(&quot;~M()&quot;);
+ std::puts("~M()");
}
};
@@ -963,11 +963,11 @@ struct option {
};
int main() {
- std::puts(&quot;==&gt; case 1&quot;);
+ std::puts("==&gt; case 1");
// invokes M(S&amp;&amp;, int)
option&lt;M&gt; opt1(S{}, 123);
- std::puts(&quot;==&gt; case 2&quot;);
+ std::puts("==&gt; case 2");
// invokes M() + M(M&amp;&amp;)
option&lt;M&gt; x /* option(M&amp;&amp;) + M(M&amp;&amp;) */ = M{} /* M() */;
}
diff --git a/development/cmake.html b/development/cmake.html
index b69f893..85ed59f 100644
--- a/development/cmake.html
+++ b/development/cmake.html
@@ -203,7 +203,7 @@ target_compile_definitions(liba INTERFACE DEF_INTERFACE)
add_executable(main main.cc)
target_link_libraries(main liba)
</code></pre>
-<pre><code class="language-sh">&gt; touch liba.cc; echo &quot;int main() {}&quot; &gt; main.cc
+<pre><code class="language-sh">&gt; touch liba.cc; echo "int main() {}" &gt; main.cc
&gt; cmake -B build -S . -G Ninja
&gt; ninja -C build -j1 --verbose
[1/4] /usr/bin/c++ -DDEF_PRIVATE -DDEF_PUBLIC [..] .../liba.cc
diff --git a/development/gcc.html b/development/gcc.html
index 3bd5c24..99a3117 100644
--- a/development/gcc.html
+++ b/development/gcc.html
@@ -213,7 +213,7 @@ accordingly to reduce number of jump instructions.
See on <a href="https://godbolt.org/z/MbTHAP">compiler explorer</a>.</p>
<p>The semantics of this hint are as follows, the compiler prioritises <code>expr == cond</code>. So <code>__builtin_expect(expr, 0)</code> means that we expect the <code>expr</code> to be <code>0</code>
most of the time.</p>
-<pre><code class="language-bash">echo &quot;
+<pre><code class="language-bash">echo "
extern void foo();
extern void bar();
void run0(int x) {
@@ -224,7 +224,7 @@ void run1(int x) {
if (__builtin_expect(x,1)) { foo(); }
else { bar(); }
}
-&quot; | gcc -O2 -S -masm=intel -o /dev/stdout -xc -
+" | gcc -O2 -S -masm=intel -o /dev/stdout -xc -
</code></pre>
<p>Will generate something similar to the following.</p>
<ul>
@@ -250,7 +250,7 @@ run1:
</code></pre>
<h2 id="abi-linux"><a class="header" href="#abi-linux">ABI (Linux)</a></h2>
<ul>
-<li>C ABI - <a href="https://www.uclibc.org/docs/psABI-x86_64.pdf">SystemV ABI</a></li>
+<li>C ABI (x86_64) - <a href="https://gitlab.com/x86-psABIs/x86-64-ABI">SystemV ABI</a></li>
<li>C++ ABI - <a href="https://itanium-cxx-abi.github.io/cxx-abi">C++ Itanium ABI</a></li>
</ul>
diff --git a/development/gcov.html b/development/gcov.html
index 49e37bd..1b7742e 100644
--- a/development/gcov.html
+++ b/development/gcov.html
@@ -203,9 +203,9 @@ generated for a single file for example such as</p>
void tell_me(int desc) {
if (desc &amp; 1) {
- std::puts(&quot;this&quot;);
+ std::puts("this");
} else {
- std::puts(&quot;that&quot;);
+ std::puts("that");
}
}
@@ -251,9 +251,9 @@ clean:
-: 4:
2: 5:void tell_me(int desc) {
2: 6: if (desc &amp; 1) {
- 2: 7: std::puts(&quot;this&quot;);
+ 2: 7: std::puts("this");
-: 8: } else {
- #####: 9: std::puts(&quot;that&quot;);
+ #####: 9: std::puts("that");
-: 10: }
2: 11:}
-: 12:
diff --git a/development/ld.so.html b/development/ld.so.html
index 952b13e..253cec4 100644
--- a/development/ld.so.html
+++ b/development/ld.so.html
@@ -194,10 +194,10 @@ Therefore the following is a code smell:</p>
<pre><code class="language-c">// at startup LD_LIBRARY_PATH=/moose
// Assume /foo/libbar.so
-setenv(&quot;LD_LIBRARY_PATH&quot;, &quot;/foo&quot;, true /* overwrite */);
+setenv("LD_LIBRARY_PATH", "/foo", true /* overwrite */);
// Will look in /moose and NOT in /foo.
-dlopen(&quot;libbar.so&quot;, RTLD_LAZY);
+dlopen("libbar.so", RTLD_LAZY);
</code></pre>
<h2 id="ld_preload-initialization-order-and-link-map"><a class="header" href="#ld_preload-initialization-order-and-link-map">LD_PRELOAD: Initialization Order and Link Map</a></h2>
<p>Libraries specified in <code>LD_PRELOAD</code> are loaded from <code>left-to-right</code> but
diff --git a/development/make.html b/development/make.html
index 3a05525..b10075f 100644
--- a/development/make.html
+++ b/development/make.html
@@ -215,12 +215,12 @@ the recipe, make provides a set of automatic variables to work with:</p>
all: foobar blabla
foo% bla%: aaa bbb bbb
- @echo &quot;@ = $@&quot;
- @echo &quot;&lt; = $&lt;&quot;
- @echo &quot;^ = $^&quot;
- @echo &quot;+ = $+&quot;
- @echo &quot;* = $*&quot;
- @echo &quot;----&quot;
+ @echo "@ = $@"
+ @echo "&lt; = $&lt;"
+ @echo "^ = $^"
+ @echo "+ = $+"
+ @echo "* = $*"
+ @echo "----"
aaa:
bbb:
diff --git a/development/pgo.html b/development/pgo.html
index fff9eb8..7a1a625 100644
--- a/development/pgo.html
+++ b/development/pgo.html
@@ -189,8 +189,8 @@ workload.</p>
#define NOINLINE __attribute__((noinline))
-NOINLINE void foo() { puts(&quot;foo()&quot;); }
-NOINLINE void bar() { puts(&quot;bar()&quot;); }
+NOINLINE void foo() { puts("foo()"); }
+NOINLINE void bar() { puts("bar()"); }
int main(int argc, char *argv[]) {
if (argc == 2) {
@@ -231,7 +231,7 @@ clang -o test test.cc -O3 -fprofile-instr-generate
# Collect profiling data from multiple runs.
for i in {0..10}; do
- LLVM_PROFILE_FILE=&quot;prof.clang/%p.profraw&quot; ./test $(seq 0 $i)
+ LLVM_PROFILE_FILE="prof.clang/%p.profraw" ./test $(seq 0 $i)
done
# Merge raw profiling data into single profile data.
diff --git a/development/python.html b/development/python.html
index 5d15d0d..4aa6ff9 100644
--- a/development/python.html
+++ b/development/python.html
@@ -183,26 +183,26 @@
def log(f: Callable[[int], None]) -&gt; Callable[[int], None]:
def inner(x: int):
- print(f&quot;log::inner f={f.__name__} x={x}&quot;)
+ print(f"log::inner f={f.__name__} x={x}")
f(x)
return inner
@log
def some_fn(x: int):
- print(f&quot;some_fn x={x}&quot;)
+ print(f"some_fn x={x}")
def log_tag(tag: str) -&gt; Callable[[Callable[[int], None]], Callable[[int], None]]:
def decorator(f: Callable[[int], None]) -&gt; Callable[[int], None]:
def inner(x: int):
- print(f&quot;log_tag::inner f={f.__name__} tag={tag} x={x}&quot;)
+ print(f"log_tag::inner f={f.__name__} tag={tag} x={x}")
f(x)
return inner
return decorator
-@log_tag(&quot;some_tag&quot;)
+@log_tag("some_tag")
def some_fn2(x: int):
- print(f&quot;some_fn2 x={x}&quot;)
+ print(f"some_fn2 x={x}")
</code></pre>
<h2 id="walrus-operator-run"><a class="header" href="#walrus-operator-run">Walrus operator [<a href="https://www.online-python.com/9T12PvmKVy">run</a>]</a></h2>
<p>Walrus operator <code>:=</code> added since <strong>python 3.8</strong>.</p>
@@ -214,20 +214,20 @@ def foo(ret: Optional[int]) -&gt; Optional[int]:
return ret
if r := foo(None):
- print(f&quot;foo(None) -&gt; {r}&quot;)
+ print(f"foo(None) -&gt; {r}")
if r := foo(1337):
- print(f&quot;foo(1337) -&gt; {r}&quot;)
+ print(f"foo(1337) -&gt; {r}")
# Example 2: while let statements
toks = iter(['a', 'b', 'c'])
while tok := next(toks, None):
- print(f&quot;{tok}&quot;)
+ print(f"{tok}")
# Example 3: list comprehension
-print([tok for t in [&quot; a&quot;, &quot; &quot;, &quot; b &quot;] if (tok := t.strip())])
+print([tok for t in [" a", " ", " b "] if (tok := t.strip())])
</code></pre>
<h2 id="unittest-run"><a class="header" href="#unittest-run"><a href="https://docs.python.org/3/library/unittest.html">Unittest</a> [<a href="https://www.online-python.com/2fit4UcbzI">run</a>]</a></h2>
<p>Run unittests directly from the command line as <br />
@@ -255,19 +255,19 @@ class MyTest(unittest.TestCase):
<pre><code class="language-python"># file: test.py
def sum(a: int, b: int) -&gt; int:
- &quot;&quot;&quot;Sum a and b.
+ """Sum a and b.
&gt;&gt;&gt; sum(1, 2)
3
&gt;&gt;&gt; sum(10, 20)
30
- &quot;&quot;&quot;
+ """
return a + b
</code></pre>
<h2 id="timeit"><a class="header" href="#timeit"><a href="https://docs.python.org/3/library/timeit.html">timeit</a></a></h2>
<p>Micro benchmarking.</p>
-<pre><code class="language-bash">python -m timeit '[x.strip() for x in [&quot;a &quot;, &quot; b&quot;]]'
+<pre><code class="language-bash">python -m timeit '[x.strip() for x in ["a ", " b"]]'
</code></pre>
</main>
diff --git a/development/symbolver.html b/development/symbolver.html
index ca84401..e771672 100644
--- a/development/symbolver.html
+++ b/development/symbolver.html
@@ -197,10 +197,10 @@ Symbol table '.dynsym' contains 342 entries:
static linking against the library.
The following dump shows that the <code>tmp</code> program linked against <code>lpthread</code> will
depend on the symbol version <code>GLIBC_2.3.2</code>, which is the default version.</p>
-<pre><code class="language-bash">&gt; echo &quot;#include &lt;pthread.h&gt;
+<pre><code class="language-bash">&gt; echo "#include &lt;pthread.h&gt;
int main() {
return pthread_cond_wait(0,0);
- }&quot; | gcc -o tmp -xc - -lpthread;
+ }" | gcc -o tmp -xc - -lpthread;
readelf -W --dyn-syms tmp | grep pthread_cond_wait;
Symbol table '.dynsym' contains 7 entries:
@@ -272,23 +272,23 @@ symbol multiple times but in different versions.</p>
// ..@ -&gt; Is the unversioned symbol.
// ..@@.. -&gt; Is the default symbol.
-__asm__(&quot;.symver func_v0,func@&quot;);
-__asm__(&quot;.symver func_v1,func@LIB_V1&quot;);
-__asm__(&quot;.symver func_v2,func@@LIB_V2&quot;);
+__asm__(".symver func_v0,func@");
+__asm__(".symver func_v1,func@LIB_V1");
+__asm__(".symver func_v2,func@@LIB_V2");
-extern &quot;C&quot; {
- void func_v0() { puts(&quot;func_v0&quot;); }
- void func_v1() { puts(&quot;func_v1&quot;); }
- void func_v2() { puts(&quot;func_v2&quot;); }
+extern "C" {
+ void func_v0() { puts("func_v0"); }
+ void func_v1() { puts("func_v1"); }
+ void func_v2() { puts("func_v2"); }
}
-__asm__(&quot;.symver _Z11func_cpp_v1i,_Z8func_cppi@LIB_V1&quot;);
-__asm__(&quot;.symver _Z11func_cpp_v2i,_Z8func_cppi@@LIB_V2&quot;);
+__asm__(".symver _Z11func_cpp_v1i,_Z8func_cppi@LIB_V1");
+__asm__(".symver _Z11func_cpp_v2i,_Z8func_cppi@@LIB_V2");
-void func_cpp_v1(int) { puts(&quot;func_cpp_v1&quot;); }
-void func_cpp_v2(int) { puts(&quot;func_cpp_v2&quot;); }
+void func_cpp_v1(int) { puts("func_cpp_v1"); }
+void func_cpp_v2(int) { puts("func_cpp_v2"); }
-void func_cpp(int) { puts(&quot;func_cpp_v2&quot;); }
+void func_cpp(int) { puts("func_cpp_v2"); }
</code></pre>
<p>Version script for <code>libfoo</code> which defines which symbols for which versions are
exported from the ELF file.</p>
@@ -296,8 +296,8 @@ exported from the ELF file.</p>
LIB_V1 {
global:
func;
- extern &quot;C++&quot; {
- &quot;func_cpp(int)&quot;;
+ extern "C++" {
+ "func_cpp(int)";
};
local:
*;
@@ -306,8 +306,8 @@ LIB_V1 {
LIB_V2 {
global:
func;
- extern &quot;C++&quot; {
- &quot;func_cpp(int)&quot;;
+ extern "C++" {
+ "func_cpp(int)";
};
} LIB_V1;
</code></pre>
@@ -339,7 +339,7 @@ Symbol table '.dynsym' contains 14 entries:
#include &lt;assert.h&gt;
// Links against default symbol in the lib.so.
-extern &quot;C&quot; void func();
+extern "C" void func();
int main() {
// Call the default version.
@@ -349,10 +349,10 @@ int main() {
typedef void (*fnptr)();
// Unversioned lookup.
- fnptr fn_v0 = (fnptr)dlsym(RTLD_DEFAULT, &quot;func&quot;);
+ fnptr fn_v0 = (fnptr)dlsym(RTLD_DEFAULT, "func");
// Version lookup.
- fnptr fn_v1 = (fnptr)dlvsym(RTLD_DEFAULT, &quot;func&quot;, &quot;LIB_V1&quot;);
- fnptr fn_v2 = (fnptr)dlvsym(RTLD_DEFAULT, &quot;func&quot;, &quot;LIB_V2&quot;);
+ fnptr fn_v1 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V1");
+ fnptr fn_v2 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V2");
assert(fn_v0 != 0);
assert(fn_v1 != 0);