From bac8a5d2822835cf47175d1162030653fadd5c09 Mon Sep 17 00:00:00 2001 From: johannst Date: Thu, 15 Feb 2024 23:29:57 +0000 Subject: deploy: 4485708c972815bbb6df7f5a228683aa855d553d --- development/c++.html | 82 +++++++++++++++++++++++----------------------- development/cmake.html | 2 +- development/gcc.html | 6 ++-- development/gcov.html | 8 ++--- development/ld.so.html | 4 +-- development/make.html | 12 +++---- development/pgo.html | 6 ++-- development/python.html | 24 +++++++------- development/symbolver.html | 44 ++++++++++++------------- 9 files changed, 94 insertions(+), 94 deletions(-) (limited to 'development') 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.
  • On gcc strict aliasing is enabled starting with -O2.

    -
    for i in {0..3} g s; do echo "-O$i $(g++ -Q --help=optimizers -O$i | grep fstrict-aliasing)"; done
    +
    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 
     // Base case with one parameter.
     template<int P>
     void show_int() {
    -    printf("%d\n", P);
    +    printf("%d\n", P);
     }
     
     // General case with at least two parameters, to disambiguate from base case.
     template<int P0, int P1, int... Params>
     void show_int() {
    -    printf("%d, ", P0);
    +    printf("%d, ", P0);
         show_int<P1, Params...>();
     }
     
    @@ -400,13 +400,13 @@ void show(const T& t) {
     // General case with at least two parameters, to disambiguate from base case.
     template<typename T0, typename T1, typename... Types>
     void show(const T0& t0, const T1& t1, const Types&... types) {
    -    std::cout << t0 << ", ";
    +    std::cout << t0 << ", ";
         show(t1, types...);
     }
     
     int main() {
         show_int<1, 2, 3, 4, 5>();
    -    show(1, 1.0, "foo", 'a');
    +    show(1, 1.0, "foo", 'a');
     }
     

    Forwarding reference (fwd ref)

    @@ -456,21 +456,21 @@ void fwd_wrapper(T&& param) { // forwarding reference int main() { { - std::puts("==> wrapper rvalue reference"); + std::puts("==> wrapper rvalue reference"); wrapper(M{}); // calls use(M&). - std::puts("==> wrapper lvalue reference"); + std::puts("==> wrapper lvalue reference"); struct M m; wrapper(m); // calls use(M&). } { - std::puts("==> fwd_wrapper rvalue reference"); + std::puts("==> fwd_wrapper rvalue reference"); fwd_wrapper(M{}); // calls use(M&&). - std::puts("==> fwd_wrapper lvalue reference"); + std::puts("==> fwd_wrapper lvalue reference"); struct M m; fwd_wrapper(m); // calls use(M&). @@ -496,8 +496,8 @@ struct any_of<T, U0, U...> : any_of<T, U...> {}; template<typename T, typename... U> constexpr bool any_of_v = any_of<T, U...>::value; -static_assert(any_of_v<int, char, bool, int>, ""); -static_assert(!any_of_v<int, char, bool, float>, ""); +static_assert(any_of_v<int, char, bool, int>, ""); +static_assert(!any_of_v<int, char, bool, float>, "");

    Example: SFINAE (enable_if)

    Provide a single entry point Invoke to call some Operations. @@ -543,16 +543,16 @@ namespace impl { template<typename Ctx, template<typename> class Op, typename... P, enable_if_bool<has_dst<Op<Ctx>>> = true> void Invoke(const Ctx& C, P... params) { - std::cout << "Invoke " << Op<Ctx>::Name << '\n'; + std::cout << "Invoke " << Op<Ctx>::Name << '\n'; typename Op<Ctx>::Return R = impl::Invoke<Ctx, Op>(C, params...); - std::cout << "returned -> " << R << '\n'; + std::cout << "returned -> " << R << '\n'; } // Invoke an OPERATION which has *NOT* a DESTINATION with arbitrary number of arguments. template<typename Ctx, template<typename> class Op, typename... P, disable_if_bool<has_dst<Op<Ctx>>> = true> void Invoke(const Ctx& C, P... params) { - std::cout << "Invoke " << Op<Ctx>::Name << " without destination." << '\n'; + std::cout << "Invoke " << Op<Ctx>::Name << " without destination." << '\n'; impl::Invoke<Ctx, Op>(C, params...); } @@ -560,7 +560,7 @@ void Invoke(const Ctx& C, P... params) { struct Ctx { void out(const char* s, unsigned v) const { - printf("%s%x\n", s, v); + printf("%s%x\n", s, v); } }; @@ -570,7 +570,7 @@ template<typename Ctx> struct OpA { using HasCtx = std::false_type; using Return = int; - static constexpr const char* const Name = "OpA"; + static constexpr const char* const Name = "OpA"; constexpr Return operator()(int a, int b) const { return a + b; @@ -581,10 +581,10 @@ template<typename Ctx> struct OpB { using HasCtx = std::true_type; using Return = void; - static constexpr const char* const Name = "OpB"; + static constexpr const char* const Name = "OpB"; Return operator()(const Ctx& C, unsigned a) const { - C.out("a = ", 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<RET>, - "RET must be default constructible"); + "RET must be default constructible"); return {}; } return std::invoke(it->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("Failed to register test " #NAME ", same name already registered!"); \ + std::puts("Failed to register test " #NAME ", same name already registered!"); \ std::abort(); \ } \ return r; \ @@ -677,10 +677,10 @@ struct registry { using REG1 = registry<void>; TEST(REG1, test1) { - std::puts("REG1::test1"); + std::puts("REG1::test1"); } TEST(REG1, test2) { - std::puts("REG1::test2"); + std::puts("REG1::test2"); } // -- Usage 2 with convenience macro wrapper. @@ -689,18 +689,18 @@ using REG2 = registry<void, bool>; #define TEST2(NAME, ...) TEST(REG2, NAME, ##__VA_ARGS__) TEST2(test1, bool val) { - printf("REG2::test1 val %d\n", val); + printf("REG2::test1 val %d\n", val); } int main() { const auto& R1 = REG1::get(); R1.dump(); - R1.invoke("test1"); - R1.invoke("test2"); + R1.invoke("test1"); + R1.invoke("test2"); const auto& R2 = REG2::get(); R2.dump(); - R2.invoke("test1", true); + R2.invoke("test1", true); return 0; } @@ -757,7 +757,7 @@ struct Entry { }; int main() { - static_assert(is_entry_v<Entry<bool>>, ""); + static_assert(is_entry_v<Entry<bool>>, ""); }

    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<A>::value, "is true"); +static_assert(is_valid<A>::value, "is true"); // * Compare template arg list with primary template, we only supplied one // arg, the second one will be defaulted as // is_valid<A, void> @@ -795,7 +795,7 @@ static_assert(is_valid<A>::value, "is true"); // * Specialization (2) matches <A, void> // * Pick the most specialized version -> (2) -static_assert(!is_valid<B>::value, "is false"); +static_assert(!is_valid<B>::value, "is false"); // * Compare template arg list with primary template, we only supplied one // arg, the second one will be defaulted as // is_valid<A, void> @@ -846,7 +846,7 @@ struct pair<int, int> { }; int main() { - static_assert(pair<int>::kind == kIntBool, ""); + static_assert(pair<int>::kind == kIntBool, ""); // * Compare template arg list with primary template, we only supplied one // arg, the second one will be defaulted as // pair<int, bool> @@ -858,7 +858,7 @@ int main() { // * (4) <int, bool> pattern does not match // * Pick the most specialized version -> (3) - static_assert(pair<char, char>::kind == kTT, ""); + static_assert(pair<char, char>::kind == kTT, ""); // * Compare template arg list against available specializations, this will // try to match the pattern <char, char> against the patterns defined in the // partial specializations. @@ -867,7 +867,7 @@ int main() { // * (4) <char, char> pattern does not match // * Pick the most specialized version -> (2) - static_assert(pair<int, int>::kind == kIntInt, ""); + static_assert(pair<int, int>::kind == kIntInt, ""); // * Compare template arg list against available specializations, this will // try to match the pattern <int, int> against the patterns defined in the // partial specializations. @@ -876,7 +876,7 @@ int main() { // * (4) <int, int> pattern does not match // * Pick the most specialized version -> (3) - static_assert(pair<char, short>::kind == kPrimary, ""); + static_assert(pair<char, short>::kind == kPrimary, ""); // * Compare template arg list against available specializations, this will // try to match the pattern <char, short> against the patterns defined in the // partial specializations. @@ -897,25 +897,25 @@ struct S {}; struct M { M() { - std::puts("M()"); + std::puts("M()"); } M(const M&) { - std::puts("M(M&)"); + std::puts("M(M&)"); } M(M&&) { - std::puts("M(M&&)"); + std::puts("M(M&&)"); } M& operator=(const M&) = delete; M& operator=(M&&) = delete; M(S&, int) { - std::puts("M(S&)"); + std::puts("M(S&)"); } M(S&&, int) { - std::puts("M(S&&)"); + std::puts("M(S&&)"); } ~M() { - std::puts("~M()"); + std::puts("~M()"); } }; @@ -963,11 +963,11 @@ struct option { }; int main() { - std::puts("==> case 1"); + std::puts("==> case 1"); // invokes M(S&&, int) option<M> opt1(S{}, 123); - std::puts("==> case 2"); + std::puts("==> case 2"); // invokes M() + M(M&&) option<M> x /* option(M&&) + M(M&&) */ = 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) -

    > touch liba.cc; echo "int main() {}" > main.cc
    +
    > touch liba.cc; echo "int main() {}" > main.cc
     > cmake -B build -S . -G Ninja
     > 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 compiler explorer.

    The semantics of this hint are as follows, the compiler prioritises expr == cond. So __builtin_expect(expr, 0) means that we expect the expr to be 0 most of the time.

    -
    echo "
    +
    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(); }
     }
    -" | gcc -O2 -S -masm=intel -o /dev/stdout -xc -
    +" | gcc -O2 -S -masm=intel -o /dev/stdout -xc -
     

    Will generate something similar to the following.

      @@ -250,7 +250,7 @@ run1:

    ABI (Linux)

    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

    void tell_me(int desc) { if (desc & 1) { - std::puts("this"); + std::puts("this"); } else { - std::puts("that"); + std::puts("that"); } } @@ -251,9 +251,9 @@ clean: -: 4: 2: 5:void tell_me(int desc) { 2: 6: if (desc & 1) { - 2: 7: std::puts("this"); + 2: 7: std::puts("this"); -: 8: } else { - #####: 9: std::puts("that"); + #####: 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:

    // at startup LD_LIBRARY_PATH=/moose
     
     // Assume /foo/libbar.so
    -setenv("LD_LIBRARY_PATH", "/foo", true /* overwrite */);
    +setenv("LD_LIBRARY_PATH", "/foo", true /* overwrite */);
     
     // Will look in /moose and NOT in /foo.
    -dlopen("libbar.so", RTLD_LAZY);
    +dlopen("libbar.so", RTLD_LAZY);
     

    Libraries specified in LD_PRELOAD are loaded from left-to-right 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:

    all: foobar blabla foo% bla%: aaa bbb bbb - @echo "@ = $@" - @echo "< = $<" - @echo "^ = $^" - @echo "+ = $+" - @echo "* = $*" - @echo "----" + @echo "@ = $@" + @echo "< = $<" + @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.

    #define NOINLINE __attribute__((noinline)) -NOINLINE void foo() { puts("foo()"); } -NOINLINE void bar() { puts("bar()"); } +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="prof.clang/%p.profraw" ./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]) -> Callable[[int], None]: def inner(x: int): - print(f"log::inner f={f.__name__} x={x}") + print(f"log::inner f={f.__name__} x={x}") f(x) return inner @log def some_fn(x: int): - print(f"some_fn x={x}") + print(f"some_fn x={x}") def log_tag(tag: str) -> Callable[[Callable[[int], None]], Callable[[int], None]]: def decorator(f: Callable[[int], None]) -> Callable[[int], None]: def inner(x: int): - print(f"log_tag::inner f={f.__name__} tag={tag} x={x}") + print(f"log_tag::inner f={f.__name__} tag={tag} x={x}") f(x) return inner return decorator -@log_tag("some_tag") +@log_tag("some_tag") def some_fn2(x: int): - print(f"some_fn2 x={x}") + print(f"some_fn2 x={x}")

    Walrus operator [run]

    Walrus operator := added since python 3.8.

    @@ -214,20 +214,20 @@ def foo(ret: Optional[int]) -> Optional[int]: return ret if r := foo(None): - print(f"foo(None) -> {r}") + print(f"foo(None) -> {r}") if r := foo(1337): - print(f"foo(1337) -> {r}") + print(f"foo(1337) -> {r}") # Example 2: while let statements toks = iter(['a', 'b', 'c']) while tok := next(toks, None): - print(f"{tok}") + print(f"{tok}") # Example 3: list comprehension -print([tok for t in [" a", " ", " b "] if (tok := t.strip())]) +print([tok for t in [" a", " ", " b "] if (tok := t.strip())])

    Unittest [run]

    Run unittests directly from the command line as
    @@ -255,19 +255,19 @@ class MyTest(unittest.TestCase):

    # file: test.py
     
     def sum(a: int, b: int) -> int:
    -    """Sum a and b.
    +    """Sum a and b.
     
         >>> sum(1, 2)
         3
     
         >>> sum(10, 20)
         30
    -    """
    +    """
         return a + b
     

    timeit

    Micro benchmarking.

    -
    python -m timeit '[x.strip() for x in ["a ", " b"]]'
    +
    python -m timeit '[x.strip() for x in ["a ", " b"]]'
     
    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 tmp program linked against lpthread will depend on the symbol version GLIBC_2.3.2, which is the default version.

    -
    > echo "#include <pthread.h>
    +
    > echo "#include <pthread.h>
             int main() {
               return pthread_cond_wait(0,0);
    -        }" | 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.

    // ..@ -> Is the unversioned symbol. // ..@@.. -> Is the default symbol. -__asm__(".symver func_v0,func@"); -__asm__(".symver func_v1,func@LIB_V1"); -__asm__(".symver func_v2,func@@LIB_V2"); +__asm__(".symver func_v0,func@"); +__asm__(".symver func_v1,func@LIB_V1"); +__asm__(".symver func_v2,func@@LIB_V2"); -extern "C" { - void func_v0() { puts("func_v0"); } - void func_v1() { puts("func_v1"); } - void func_v2() { puts("func_v2"); } +extern "C" { + void func_v0() { puts("func_v0"); } + void func_v1() { puts("func_v1"); } + void func_v2() { puts("func_v2"); } } -__asm__(".symver _Z11func_cpp_v1i,_Z8func_cppi@LIB_V1"); -__asm__(".symver _Z11func_cpp_v2i,_Z8func_cppi@@LIB_V2"); +__asm__(".symver _Z11func_cpp_v1i,_Z8func_cppi@LIB_V1"); +__asm__(".symver _Z11func_cpp_v2i,_Z8func_cppi@@LIB_V2"); -void func_cpp_v1(int) { puts("func_cpp_v1"); } -void func_cpp_v2(int) { puts("func_cpp_v2"); } +void func_cpp_v1(int) { puts("func_cpp_v1"); } +void func_cpp_v2(int) { puts("func_cpp_v2"); } -void func_cpp(int) { puts("func_cpp_v2"); } +void func_cpp(int) { puts("func_cpp_v2"); }

    Version script for libfoo which defines which symbols for which versions are exported from the ELF file.

    @@ -296,8 +296,8 @@ exported from the ELF file.

    LIB_V1 { global: func; - extern "C++" { - "func_cpp(int)"; + extern "C++" { + "func_cpp(int)"; }; local: *; @@ -306,8 +306,8 @@ LIB_V1 { LIB_V2 { global: func; - extern "C++" { - "func_cpp(int)"; + extern "C++" { + "func_cpp(int)"; }; } LIB_V1;
    @@ -339,7 +339,7 @@ Symbol table '.dynsym' contains 14 entries: #include <assert.h> // Links against default symbol in the lib.so. -extern "C" 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, "func"); + fnptr fn_v0 = (fnptr)dlsym(RTLD_DEFAULT, "func"); // Version lookup. - fnptr fn_v1 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V1"); - fnptr fn_v2 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V2"); + 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); -- cgit v1.2.3