#til notes

Random bits I posted on twitter or wrote down for myself. Last update 2023-03-04


Go: it's not possible to JSON encode (encoding/json) structures having function fields, like

type t struct {
    callback func()
}

AVX-512: set k-reg to all ones: KXNOR K1, K1, K1 (kxnor = not (x xor y))


Go: go doc -u show documentation also for private entities


Go: package rutime/debug provides PrintStack() that prints the call trace of the current routine.


Maths: the radius of circle inscribed inside a equilateral triangle of side a is (√3a)/6.


C: strtod does not reset errono


C++: std::map & std::set have method extract(key) that find-and-removes node if the key's present


C: GCC and clang can inline function called via a known pointer

int calc1(int num) {
    return num * num;
}

int calc2(int num) {
        return 5 * num;
}

// "template"
int calc(int x, int (*fun)(int)) {
    return fun(x);
}

// specialisations
int calc_fun1(int x) {
    return calc(x, calc1);
}

int calc_fun2(int x) {
        return calc(x, calc2);
}
calc_fun1:
        movl    %edi, %eax
        imull   %edi, %eax
        ret
calc_fun2:
        leal    (%rdi,%rdi,4), %eax
        ret

C: GCC and clang inline bsearch, but not qsort.


Python: pickle module always serializes objects in memory, even when the serialization target is a file


GCC: print all predefined macros:

gcc -dM -E - < /dev/null

Python: strange closure binding rules

class Foo(object):
    def proc(self):
        print "Foo"

class Bar(object):
    def proc(self):
        print "Bar"

x = Foo()
call_foo = lambda: x.proc()

x = Bar()
call_bar = lambda: x.proc()

call_foo()
call_bar()

This code will print "Bar" twice.


Python: make the standard output utf8-friendly

import sys
import codecs

sys.stdout = codecs.getwriter('utf-8')(sys.stdout)

Python: do not fail when pipe output to another program and that program closes

from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)

C++ preprocessor: macros that have references to another macro do not keep its copy. When the referenced macro is undefined (with #undef), then one which used it becomes invalid.

#define value 5
#define add(x) ((x) + value)

int main() {
    int x = 3;

    x = add(5);
#undef value
    x = add(6); // error: ‘value’ undeclared (first use in this function)
}

C++: std::atomic_bool has the default construct that left the atomic uninitialized.


Linux: there's a nice tool gstack, that prints the current stacktrace of given process (all process' threads).


C++: std::optional has a useful method value_or(), which returns a default value in case the optional is empty.


GCC: When compiled with the address sanitizer it is possible to catch std::terminate, as the sanitizer injects own handlers and they can be intercepted by gdb.


C++: as the order of evaluation function's arguments is undefined, fun might got the second parameter 0 when move was evaluated first.

fun(std::move(vector), vector.size());

C++: you can omit parentheses in lambda expression if the lambda takes no arguments; auto lambda = []{}; is valid


C++: std::regex doesn't hold the string it was built from


C++: the final keyword doesn't imply override.


C++: macros don't go with templates.

#include <map>
#define decl(name, type) type name

decl(kitten, int); // OK
decl(nope, std::map<int,bool>); // error: macro "decl" passed 3 arguments, but takes just 2

C++: It's possible to directly compare an optional with a value, like std::optional<T>() == T().


C++11: although it's possible to pass by reference this pointer to a lambda and return such lambda outside the class, the reference becomes invalid when instance is destroyed.

#include <functional>
#include <string>
#include <cstdlib>

struct Foo {

    int counter;
    int* ptr;

    Foo() : ptr(&counter) {}
    ~Foo() {
        puts("destroyed");
        ptr = nullptr;
    }

    std::string s;

    std::function<void()> getfun() {
        return [this]() {
            *ptr += 1;
        };
    }
};

int main() {

    std::function<void()> fun;

    {
        Foo f{};
        fun = f.getfun();
        fun();
        fun();
    }

    // program prints "destroyed" and ...
    fun(); // ... segfaults here
}

C++ odds: there's no name clash between variables and classes; following program is perfectly valid:

int foo;
class foo {};

GCC provides useful cpp-related warnings (not enabled by -Wall): -Wsuggest-final-types, -Wsuggest-final-methods, -Wsuggest-override


C++17: std::regex doesn't hold the string it was built from; pretty unhandy feature


C++: GCC 7/clang 5, invoked with at least -O2, remove at() invocation in such a loop:

for (size_t i=0; i < vec.size(); i++)
    function(vec.at(i));

C++17: std::move is impossible on std::reference_wrapper


C++17: std::filesystem::remove_all(path) asserts that the path exists and throws an exception otherwise; boost::filesystem::remove_all does nothing in such case


SQLite: foreign keys have to be enabled manually by command PRAGMA foreign_key = on


C++17: std::optional doesn't accept references, while boost::optional does


C++: std::unique_ptr<T>(nullptr) == nullptr yields true


SSE intrinsics: _mm_extract_ps returns an integer, the suffix "ps" suggests a float


C++: std::list::size() is constant time since C++11


MSVC doesn't support a warning directive; instead it has a pragma: message("text")


C++: sizeof(type*) == sizeof(std::unique_ptr<type>)


C++: std::unordered_map has got method at()


GCC/clang: -Wfatal-errors stops compilation on the first error