From e99b4bdfb2d89f4463e126c292332d3cf50eab20 Mon Sep 17 00:00:00 2001 From: Alexis Pereda Date: Tue, 2 Jul 2019 17:21:34 +0200 Subject: [PATCH] [et] first draft --- README.md | 41 ++++++++++++++++++++++++++++++ examples/et/1_first_draft.cpp | 48 +++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 examples/et/1_first_draft.cpp diff --git a/README.md b/README.md index ed87e55..705dc2c 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,44 @@ make ``` then run any example binary, located inside the `build/examples/` directory. + +## Remarks + +### Assembler code + +Some examples are meant to show the assembler code they generate. +To see that, one can use for example https://godbolt.org/ or GDB. +With GDB: +```bash +gdb -q -ex 'disassemble main' -ex q "${program_to_execute}" +``` + +Important note: +if using `cmake` to produce the Makefile, you must call it with at least: +```bash +cmake -DCMAKE_BUILD_TYPE=Release .. +``` +or the examples will be compiled without the optimization level 2. + +### use of `volatile` + +When a value is required to show something, it is necessary to prevent the compiler to +optimize out this value. To achieve this, one can read the value from a file, for example, +but it will generate more assembler code. +Another solution is the `volatile` type modifier that forbids optimization like caching or +other optimizations like: +```cpp +int main() { + int volatile v0 = 5, v1 = 7; + return v0 + v1; +} +``` + +Without `volatile`, the addition is done by the compiler and `main` returns directly `12`. +With `volatile`, the generated assembler code will contain an `add` instruction, even with `-O2`. + +### `std::printf` instead of `std::cout` + +C++ iostreams cause lots of assembler code, for that reason, when an example is expected to be +possibly used by looking at its generated assembler code, iostreams are avoided and replaced by +`printf`. diff --git a/examples/et/1_first_draft.cpp b/examples/et/1_first_draft.cpp new file mode 100644 index 0000000..faea1fd --- /dev/null +++ b/examples/et/1_first_draft.cpp @@ -0,0 +1,48 @@ +#include + +struct Add { + template + static auto eval(T lhs, T rhs) { + return lhs + rhs; + } +}; + +struct Mul { + template + static auto eval(T lhs, T rhs) { + return lhs * rhs; + } +}; + +template +class Value { + T _value; + +public: + Value(T value): _value(value) {} + + auto eval() const { return _value; } +}; + +template +struct BinExpr { + LHS lhs; + RHS rhs; + + auto eval() const { + return Op::eval(lhs.eval(), rhs.eval()); + } +}; + +int main() { + using SubExpr = BinExpr, Value>; + using MyExpr = BinExpr, SubExpr>; + + int volatile v0 = 3, v1 = 5, v2 = 7; + int result; + + MyExpr expr{{v0}, {{v1}, {v2}}}; + result = expr.eval(); + + std::printf("%d\n", result); +}