<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged cplusplus</title>
<link>https://coderlegion.com/tag/cplusplus</link>
<description>Powered by Question2Answer</description>
<item>
<title>Tuesday Coding Tip 20 — Be `explicit`!</title>
<link>https://coderlegion.com/21475/tuesday-coding-tip-20-be-explicit</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If you choose to add a conversion operator for your class in C++, be sure to mark it as &lt;code&gt;explicit&lt;/code&gt; or you can get nasty side-effects that will be hard to debug. For example, having an implicit conversion operator to bool will make the operator less-than “work” for your class, meaning that class can be used as a key for &lt;code&gt;std::map&lt;/code&gt; and suddenly, all hell breaks loose.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;

class A {
public:
    operator bool() {
        return true;
    }
};

class B {
public:
    explicit operator bool() {
        return true;
    }
};

int main() {
    // This is ok
    std::cout &amp;lt;&amp;lt; (A() &amp;lt; A()) &amp;lt;&amp;lt; std::endl;
    A a;
    if (a); // implicit conversion allowed

    // Error: error: invalid operands to binary expression
    std::cout &amp;lt;&amp;lt; (B() &amp;lt; B()) &amp;lt;&amp;lt; std::endl;
    B b;
    if (bool(b)); // explicit conversion required

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, it is good practice to mark single parameter constructors &lt;code&gt;explicit&lt;/code&gt; to prevent implicit conversions from trivial data types or to possibly track places where your object is copied.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class A {
public:
    A(int) {}
    A(const A&amp;amp;) {}
};

class B {
public:
    explicit B(int) {}
    explicit B(const B&amp;amp;) {}
};

int main() {
    A a1 = 10; // ok
    A a2 = { 10 }; // ok
    A a3 = a1; // ok

    B b1 = 10; // error: no viable conversion, explicit constructor is not a candidate
    B b2 = { 10 }; // error
    B b3 = B{10}; // ok
    B b4 = b1; // error
    B b5 = B{b1}; // ok

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21475/tuesday-coding-tip-20-be-explicit</guid>
<pubDate>Tue, 21 Jul 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 19 — [[nodiscard]] annotation</title>
<link>https://coderlegion.com/21474/tuesday-coding-tip-19-nodiscard-annotation</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Since C++17, one can use &lt;code&gt;[[nodiscard]]&lt;/code&gt; annotation to mark API functions whose return values should not be discarded without consideration. This usually applies to methods that make no sense to call without evaluating their return value (like predicate functions such as &lt;code&gt;empty&lt;/code&gt; or a factory function). The compiler will issue a warning if the return value is not handled.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class [[nodiscard]] A {};

// OR

class B {
public:
    [[nodiscard]] B() = default;
};

// Enums can be nodiscard too
enum class [[nodiscard]] State {
    Default,
    Foo,
    Bar
};

int main()
{
    // warning: ignoring temporary created by a constructor declared with 'nodiscard' attribute
    A();
    B();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But beware! Sometimes it might be tempting to return some scope guard that will maintain postconditions automatically at the end of the scope using RAII (such as committing transactions). However, a user of your API can pipe the result of your &lt;code&gt;nodiscard&lt;/code&gt; function into a &lt;code&gt;std::ignore&lt;/code&gt; helper which causes the temporary to destruct immediately, defeating the idea of end-of-scope cleanup.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;tuple&amp;gt; // std::ignore

class [[nodiscard]] A {};
class B {
public:
    [[nodiscard]] bool isOk() const { return true; }
};

// no need for nodiscard, A is nodiscard
A foo() {
    return A();
}

// B is not nodiscard, mark it explicitly
[[nodiscard]] B bar() {
    return B();
}

int main()
{    
    foo(); // warning: ignoring temporary created by a constructor declared with 'nodiscard' attribute
    bar(); // warning

    std::ignore = foo(); // ok
    auto b = bar(); // ok
    b.isOk(); // warning
    if (b.isOk()) {} // ok
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21474/tuesday-coding-tip-19-nodiscard-annotation</guid>
<pubDate>Tue, 14 Jul 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 18 — Generating random numbers in C++</title>
<link>https://coderlegion.com/21473/tuesday-coding-tip-18-generating-random-numbers-in-c</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Classic C way of generating random numbers is to set the current time as a seed and then modulo results of the rand function to get somewhat random numbers (modulo can introduce bias based on the implementation of rand).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;random&amp;gt;

// Get random integer in range &amp;lt;min, max)
int getRandomNumber(int min, int max)
{
    return rand() % (max - min) + min;
}

int main()
{
    // seeding with current time to get different output each time
    srand(time(NULL));

    for (int i = 0; i &amp;lt; 10; i++)
        std::cout &amp;lt;&amp;lt; getRandomNumber(10, 20) &amp;lt;&amp;lt; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C++11 introduces the concept of engines, adaptors, and distributions. Engines are seedable and give you random numbers similar to &lt;code&gt;rand()&lt;/code&gt; calls. However, each engine is implemented differently, impacting its speed and memory footprint. Adapters tamper with RNG output, such as shuffling the order of output values or discarding them.&lt;/p&gt;
&lt;p&gt;Distributions transform the output from the generators to get values in certain ranges and probabilistic properties, such as the middle value being the most probable (normal distribution). Distributions are more nuanced than just using the modulo operator so their outputs are more suitable for cryptography use-cases.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;random&amp;gt;

// Get random integer in range &amp;lt;min, max)
int getRandomNumber(int min, int max)
{
    return rand() % (max - min) + min;
}

int main()
{
    std::random_device rd; // non-seedable source of non-deterministic numbers from hardware
    std::mt19937 generator(rd()); // deterministic generator with uniform distribution
                                  // seeded with totally random number

    std::uniform_int_distribution&amp;lt;&amp;gt; distribution(10, 19);

    for (int i = 0; i &amp;lt; 10; i++)
        std::cout &amp;lt;&amp;lt; distribution(generator) &amp;lt;&amp;lt; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21473/tuesday-coding-tip-18-generating-random-numbers-in-c</guid>
<pubDate>Tue, 07 Jul 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 17 — Wrapping C APIs</title>
<link>https://coderlegion.com/21472/tuesday-coding-tip-17-wrapping-c-apis</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Resource Acquisition is Initialization (RAII) is an awfully named principle saying that your class should be fully usable after construction and should clean itself up in the destructor (in other words, no (de)init methods). This principle is common in modern programming languages and is also adopted in modern C++ codebases.&lt;/p&gt;
&lt;p&gt;But what if you work with C-like API like &lt;code&gt;fopen&lt;/code&gt;? It returns a pointer you need to manually free before it goes out of scope. Otherwise, you leak memory and open file handles. This is where smart pointers come to the rescue as you can wrap raw pointers with them and give them custom callbacks to execute when they leave the scope.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;cstdlib&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;memory&amp;gt;

// MSVC disallows calling fopen
#pragma warning(disable : 4996)

void CloseFile(FILE* f)
{
    std::cout &amp;lt;&amp;lt; &quot;Closing file&quot; &amp;lt;&amp;lt; std::endl;
    fclose(f);
}

auto SafeFopen(const char* path, const char* mode)
{
    return std::unique_ptr&amp;lt;FILE, decltype(&amp;amp;CloseFile)&amp;gt;(
        fopen(path, mode), CloseFile);
}

int main()
{
    auto&amp;amp;&amp;amp; fp = SafeFopen(&quot;myfile.txt&quot;, &quot;w&quot;);
    return 0;
    // Outputs: Closing file
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21472/tuesday-coding-tip-17-wrapping-c-apis</guid>
<pubDate>Tue, 30 Jun 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 16 — Creating objects in existing memory</title>
<link>https://coderlegion.com/19946/tuesday-coding-tip-16-creating-objects-in-existing-memory</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;C++ allows you to scrap your OS’ memory allocators, get yourself a huge chunk of memory and write your own allocators (they can be used with the standard library). It’s a hardcore optimization, but here’s a related tip that might be handy in normal projects as well.&lt;/p&gt;
&lt;p&gt;When using the operator &lt;code&gt;new&lt;/code&gt;, one can provide it with an already allocated memory, so it runs a constructor for a particular type in there. After that, reinterpret that memory as a pointer to your desired object and use it normally. However, deletion is a bit more complicated, as you have to call the destructor on that object manually (because &lt;code&gt;delete&lt;/code&gt; must be called on the original memory, not the object).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// using some template type T
auto&amp;amp;&amp;amp; buffer = static_cast&amp;lt;std::byte*&amp;gt;(::operator new(sizeof(T)));
if (!buffer) throw std::bad_alloc();

new (buffer) T();
auto&amp;amp;&amp;amp; object = reinterpret_cast&amp;lt;T*&amp;gt;(buffer);

// ...

object-&amp;gt;~T(); // call destructor
delete[] buffer; // properly release memory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I used this trick when implementing a resource manager that needs to hold any user data type (that is still default-constructible in my case): &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/nerudaj/dgm-lib/blob/main/lib/include/DGM/classes/ResourceManager.hpp&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/19946/tuesday-coding-tip-16-creating-objects-in-existing-memory</guid>
<pubDate>Tue, 16 Jun 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 15 — Mathematical constants in C++</title>
<link>https://coderlegion.com/19942/tuesday-coding-tip-15-mathematical-constants-in-c</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and LinkedIn.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Since C++20, you can include header &lt;code&gt;&amp;lt;numbers&amp;gt;&lt;/code&gt; and use many commonly used, precomputed mathematical constants like Pi, Phi, square root of 2 and 3, natural logarithms of 2 and 10, and many more! Even better, you can choose their precision by specifying the underlying type via a template.&lt;/p&gt;
&lt;p&gt;And since C++17, the &lt;code&gt;&amp;lt;cmath&amp;gt;&lt;/code&gt; header contains some special math functions I’ve never heard of like cylindrical Bessel functions, associated Legendre polynomials, or Riemann zeta function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;numbers&amp;gt;
#include &amp;lt;iomanip&amp;gt; // std::setprecision
#include &amp;lt;limits&amp;gt; // std::numeric_limits

template&amp;lt;typename T&amp;gt;
void printConstant(T value)
{
    const auto default_precision{std::cout.precision()};

    std::cout &amp;lt;&amp;lt; std::setprecision(std::numeric_limits&amp;lt;T&amp;gt;::digits10 + 1);
    std::cout &amp;lt;&amp;lt; value &amp;lt;&amp;lt; std::endl;

    std::cout &amp;lt;&amp;lt; std::setprecision(default_precision);
}

int main()
{
    using namespace std::numbers;
    printConstant(pi_v&amp;lt;float&amp;gt;);
    printConstant(pi_v&amp;lt;double&amp;gt;);
    printConstant(pi_v&amp;lt;long double&amp;gt;);

    /* Outputs:
    3.141593
    3.141592653589793
    3.141592653589793239
    */
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Constants are documented here: &lt;a rel=&quot;nofollow&quot; href=&quot;https://en.cppreference.com/w/cpp/numeric/constants&quot;&gt;https://en.cppreference.com/w/cpp/numeric/constants&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Special functions are documented here: &lt;a rel=&quot;nofollow&quot; href=&quot;https://en.cppreference.com/w/cpp/numeric/special_functions&quot;&gt;https://en.cppreference.com/w/cpp/numeric/special_functions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/19942/tuesday-coding-tip-15-mathematical-constants-in-c</guid>
<pubDate>Tue, 09 Jun 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 13 — Deleting problematic overloads</title>
<link>https://coderlegion.com/18836/tuesday-coding-tip-13-deleting-problematic-overloads</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Suppose you have a C++ function for opening a file stream that accepts a path to a file and a string (view) with open-mode specifications (like &lt;code&gt;fopen&lt;/code&gt;). The issue is, even though your API is strongly typed, users can still swap the arguments by accident and don’t get a compile time error, due to implicit conversions from string-like constants.&lt;/p&gt;
&lt;p&gt;Luckily, there is an easy hack with which you can disable implicit conversions for one particular function by explicitly deleting all overloads (via &lt;code&gt;auto&lt;/code&gt; template) and allowing just one particular version. The coolest thing is that even the return value doesn’t have to match!&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;filesystem&amp;gt;

using path = std::filesystem::path;

void fopen2(const auto&amp;amp;, const auto&amp;amp;) = delete;

FILE* fopen2(const path&amp;amp; fp, const std::string&amp;amp; mode)
{
    /* dummy implementation */
    return nullptr;
}

int main()
{
    // error: call to deleted function 'fopen2'
    // note: candidate function [with auto:1 = char[11], auto:2 = char[2]] has been explicitly deleted
    fopen2(&quot;myfile.txt&quot;, &quot;r&quot;);

    // This is ok
    fopen2(path { &quot;myfile.txt&quot; }, std::string { &quot;r&quot; });
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18836/tuesday-coding-tip-13-deleting-problematic-overloads</guid>
<pubDate>Tue, 26 May 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 12 — Stack trace</title>
<link>https://coderlegion.com/17200/tuesday-coding-tip-12-stack-trace</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;C++23 brings a new feature that I always wanted since I’ve seen it in C# — stack trace.&lt;/p&gt;
&lt;p&gt;When combined with exceptions, it can immensely help with the analysis of user error reports, when you cannot simply attach a debugger. The code snippet shows how to create an exception class that can automatically capture stack trace at the point where it was constructed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;stacktrace&amp;gt;
#include &amp;lt;stdexcept&amp;gt;

class stacktrace_error : public std::runtime_error
{
public:
    stacktrace_error(std::stacktrace trace = std::stacktrace::current())
        : std::runtime_error(std::to_string(trace))
    {}
};

void bar() { throw stacktrace_error(); }
void foo() { bar(); }

int main()
{
    try
    {
        foo();
    }
    catch (std::exception&amp;amp; e)
    {
        std::cerr &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; std::endl;
        /* OUTPUTS:
        0&amp;gt; C:\...\Main.cpp(19): Sandbox!bar+0x44
        1&amp;gt; C:\...\Main.cpp(25): Sandbox!foo+0x20
        2&amp;gt; C:\...\Main.cpp(31): Sandbox!main+0x32
        3&amp;gt; D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(79): Sandbox!invoke_main+0x39
        4&amp;gt; D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288): Sandbox!__scrt_common_main_seh+0x12E
        5&amp;gt; D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(331): Sandbox!__scrt_common_main+0xE
        6&amp;gt; D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp(17): Sandbox!mainCRTStartup+0xE
        7&amp;gt; KERNEL32!BaseThreadInitThunk+0x14
        8&amp;gt; ntdll!RtlUserThreadStart+0x21
        */
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The API even allows you to iterate over each stack entry, but honestly — who needs that?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Linux versions of GCC and Clang have this stupid idea of requiring you to manually link stacktrace (akin to math library), because &lt;code&gt;-std=c++23&lt;/code&gt; is apparently not enough of a feature flag. So don't forget to use &lt;code&gt;-lstdc++_libbacktrace&lt;/code&gt; argument for compilation.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/17200/tuesday-coding-tip-12-stack-trace</guid>
<pubDate>Tue, 19 May 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>UltrafastSecp256k1 v4.0 — Optional Secondary secp256k1 Backend for Evaluation</title>
<link>https://coderlegion.com/18131/ultrafastsecp256k1-v4-0-optional-secondary-secp256k1-backend-for-evaluation</link>
<description>&lt;p&gt;Overview&lt;br&gt;
UltrafastSecp256k1 v4.0 is a high-performance secp256k1 engine built for evaluation as an optional secondary backend for Bitcoin Core. The goal is not to replace libsecp256k1, but to make it possible to measure, compare, and selectively enable an alternative implementation under controlled conditions.&lt;/p&gt;
&lt;p&gt;This post presents the current state of the project, its integration model, and the evidence gathered through continuous audit infrastructure.&lt;/p&gt;
&lt;p&gt;Repository: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/UltrafastSecp256k1&quot;&gt;https://github.com/shrec/UltrafastSecp256k1&lt;/a&gt; Release v4.0.0: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/UltrafastSecp256k1/releases/tag/v4.0.0&quot;&gt;https://github.com/shrec/UltrafastSecp256k1/releases/tag/v4.0.0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Integration Model&lt;br&gt;
Integration uses a shim layer that exposes the identical secp256k1.h API surface. Bitcoin Core can be built with the alternative backend using a single CMake flag:&lt;/p&gt;
&lt;p&gt;cmake -B build -DSECP256K1_BACKEND=ultrafast&lt;br&gt;
cmake --build build&lt;br&gt;
The default backend remains libsecp256k1 unchanged. All existing Bitcoin Core C++ source files remain unmodified — only the CMake build system references a different library.&lt;/p&gt;
&lt;p&gt;Fork demonstrating this integration: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/bitcoin/tree/feature/ultrafast-secp256k1-backend&quot;&gt;https://github.com/shrec/bitcoin/tree/feature/ultrafast-secp256k1-backend&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Shim API coverage:&lt;/p&gt;
&lt;p&gt;secp256k1.h — context, pubkey, seckey&lt;br&gt;
secp256k1_extrakeys.h — keypair, x-only pubkey (BIP-340/341)&lt;br&gt;
secp256k1_schnorrsig.h — Schnorr sign/verify (BIP-340)&lt;br&gt;
secp256k1_ecdh.h — ECDH&lt;br&gt;
secp256k1_recovery.h — ECDSA recovery&lt;br&gt;
secp256k1_ellswift.h — ElligatorSwift (BIP-324)&lt;br&gt;
secp256k1_musig.h — MuSig2 (BIP-327, all 14 functions)&lt;br&gt;
Performance — Bitcoin Core Integration Paths&lt;br&gt;
All numbers from bench_bitcoin (Bitcoin Core's native benchmark harness) on Intel i5-14400F, GCC 14.2.0, Release+LTO, intel_pstate/no_turbo=1, taskset -c 0, nice -20, 5 runs.&lt;/p&gt;
&lt;p&gt;Canonical artifact: docs/BITCOIN_CORE_BENCH_RESULTS.json&lt;/p&gt;
&lt;p&gt;Transaction signing:&lt;/p&gt;
&lt;p&gt;BenchmarkUltralibsecp256k1Delta&lt;br&gt;
SignSchnorrWithMerkleRoot83.9 µs113.4 µs+35% faster&lt;br&gt;
SignSchnorrWithNullMerkleRoot84.0 µs113.0 µs+35% faster&lt;br&gt;
SignTransactionECDSA149.5 µs165.1 µs+10% faster&lt;br&gt;
SignTransactionSchnorr125.4 µs137.5 µs+10% faster&lt;br&gt;
Script verification:&lt;/p&gt;
&lt;p&gt;BenchmarkUltralibsecp256k1Delta&lt;br&gt;
VerifyScriptP2TR_KeyPath45.4 µs46.3 µs+2.0% faster&lt;br&gt;
VerifyScriptP2TR_ScriptPath76.5 µs83.8 µs+10% faster&lt;br&gt;
VerifyScriptP2WPKH46.0 µs45.8 µsparity (within noise)&lt;br&gt;
Block validation aggregate (ConnectBlock, 2000 unique signatures):&lt;/p&gt;
&lt;p&gt;ScenarioUltralibsecp256k1Delta&lt;br&gt;
All ECDSA254.3 ms257.4 ms+1.2% faster&lt;br&gt;
All Schnorr253.0 ms255.3 ms+0.9% faster&lt;br&gt;
Mixed (2k Schnorr + 1k ECDSA)253.9 ms257.7 ms+1.5% faster&lt;br&gt;
Without LTO: ConnectBlock is ~0.5–1.0% slower than libsecp256k1 due to i-cache pressure from a larger code footprint. LTO is required for Ultra to win the aggregate. This tradeoff is documented in docs/SHIM_KNOWN_DIVERGENCES.md.&lt;/p&gt;
&lt;p&gt;Bitcoin Core test suite: 749/749 passing with Ultra backend (GCC 14.2.0, May 2026).&lt;/p&gt;
&lt;p&gt;Performance — Constant-Time Signing Primitives&lt;br&gt;
From docs/bench_unified_2026-05-16_gcc14_x86-64.json. CT-vs-CT co-measured in the same run (ratios are TSC-independent):&lt;/p&gt;
&lt;p&gt;OperationUltra CTlibsecp256k1Ratio&lt;br&gt;
CT ECDSA sign21.6 µs59.7 µs1.30× faster&lt;br&gt;
CT Schnorr sign (BIP-340)18.1 µs46.5 µs1.28× faster&lt;br&gt;
Schnorr verify84.3 µs84.3 µsequal&lt;br&gt;
Field arithmetic primitives:&lt;/p&gt;
&lt;p&gt;PrimitiveUltralibsecp256k1Ratio&lt;br&gt;
field_mul20.1 ns26.5 ns1.32×&lt;br&gt;
field_sqr18.7 ns22.3 ns1.19×&lt;br&gt;
field_inv1253.9 ns1506.0 ns1.20×&lt;br&gt;
field_from_bytes4.8 ns13.0 ns2.71×&lt;br&gt;
Continuous Audit and Assurance (CAAS)&lt;br&gt;
The repository includes a continuous audit infrastructure tracking security regressions across every commit.&lt;/p&gt;
&lt;p&gt;Current state at v4.0.0:&lt;/p&gt;
&lt;p&gt;262 exploit PoC modules covering 20+ CVE/attack classes — all pass&lt;br&gt;
369 total audit modules (262 exploit PoC + 107 non-exploit)&lt;br&gt;
CAAS autonomy score: 100/100 (8/8 gates)&lt;br&gt;
Source: docs/SECURITY_AUTONOMY_KPI.json&lt;/p&gt;
&lt;p&gt;Audit surfaces include: nonce reuse, side-channel timing (dudect), CT boundary verification, batch verify soundness, MuSig2/FROST protocol attacks, adaptor signatures, DER BIP-66 strict parsing, BIP-340/RFC-6979 known-answer tests, Wycheproof vectors, structure-aware fuzzing, differential testing vs libsecp256k1, and Python-based algebraic property testing.&lt;/p&gt;
&lt;p&gt;Security properties enforced:&lt;/p&gt;
&lt;p&gt;Constant-time signing: ECDSA, Schnorr, MuSig2, FROST, BIP-324 XDH&lt;br&gt;
Per-context DPA blinding (secp256k1_context_randomize fully implemented)&lt;br&gt;
Strict scalar parsing for private key inputs (parse_bytes_strict_nonzero)&lt;br&gt;
Fail-closed batch signing APIs&lt;br&gt;
BIP-66 strict DER enforcement in all shim paths&lt;br&gt;
Benchmarking Methodology&lt;br&gt;
Benchmarks distinguish between:&lt;/p&gt;
&lt;p&gt;CT vs CT — constant-time Ultra signing vs constant-time libsecp signing (production-equivalent, fair comparison)&lt;br&gt;
Bitcoin Core integration — bench_bitcoin binary, real validation pipeline&lt;br&gt;
LTO vs no-LTO — both measured and documented&lt;br&gt;
Warm-cache vs cold-cache — noted where applicable&lt;br&gt;
All claimed improvements include error percentage from nanobench's internal statistics. Inconclusive results (overlapping ranges) are reported as such. Results are reproducible from the canonical JSON artifacts in the repository.&lt;/p&gt;
&lt;p&gt;Reproducibility&lt;br&gt;
Builds are deterministic:&lt;/p&gt;
&lt;p&gt;-ffile-prefix-map strips source paths from debug info&lt;br&gt;
SOURCE_DATE_EPOCH awareness&lt;br&gt;
Fixed -march=x86-64-v3 (no host-native variation)&lt;br&gt;
SLSA provenance attached to v4.0.0 release artifacts (via Sigstore/Cosign)&lt;br&gt;
Platform Coverage&lt;br&gt;
CI passing on all platforms as of v4.0.0:&lt;/p&gt;
&lt;p&gt;PlatformArchitectureCompiler&lt;br&gt;
Linuxx86-64-v3GCC 14 / Clang 17&lt;br&gt;
LinuxARM64GCC 14&lt;br&gt;
LinuxRISC-V 64GCC 14&lt;br&gt;
macOSARM64 (Apple Silicon)Clang 15&lt;br&gt;
Windowsx86-64MSVC / GCC&lt;br&gt;
Additional: Android ARM64 (NDK), WASM, ESP32, STM32.&lt;/p&gt;
&lt;p&gt;Known Limitations&lt;br&gt;
ConnectBlock improvement requires Release+LTO. Without LTO: ~0.5–1.0% slower than libsecp256k1.&lt;br&gt;
GPU backends (CUDA, OpenCL, Metal) are present but not part of the Bitcoin Core evaluation profile.&lt;br&gt;
This covers the CPU backend only.&lt;br&gt;
Current Objective&lt;br&gt;
No mandatory integration path is proposed. The current objective is to make an alternative backend available for evaluation on technical grounds, with reproducible evidence, minimal integration surface, and an easy rollback path.&lt;/p&gt;
&lt;p&gt;The default backend remains libsecp256k1. All existing behavior is preserved unless the new backend is explicitly enabled at build time.&lt;/p&gt;
&lt;p&gt;Reviewer Entry Path&lt;br&gt;
git clone &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/shrec/UltrafastSecp256k1&quot;&gt;https://github.com/shrec/UltrafastSecp256k1&lt;/a&gt;&lt;br&gt;
cd UltrafastSecp256k1&lt;br&gt;
python3 ci/verify_external_audit_bundle.py --allow-commit-mismatch&lt;br&gt;
Key documents:&lt;/p&gt;
&lt;p&gt;docs/BITCOIN_CORE_BACKEND_EVIDENCE.md — full reviewer package&lt;br&gt;
docs/BENCHMARKS.md — benchmark methodology and raw data&lt;br&gt;
docs/AUDIT_CHANGELOG.md — security audit history&lt;br&gt;
docs/SHIM_KNOWN_DIVERGENCES.md — documented behavioral differences from libsecp256k1&lt;br&gt;
All performance numbers are from controlled benchmark runs with hard turbo lock. Raw data available in the repository. Canonical benchmark artifact: docs/BITCOIN_CORE_BENCH_RESULTS.json, docs/bench_unified_2026-05-16_gcc14_x86-64.json.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18131/ultrafastsecp256k1-v4-0-optional-secondary-secp256k1-backend-for-evaluation</guid>
<pubDate>Sun, 17 May 2026 00:46:15 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 10— CTest</title>
<link>https://coderlegion.com/15918/tuesday-coding-tip-10-ctest</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;CMake can do many things and instrumenting your test suite is one of them. Use &lt;code&gt;add_test&lt;/code&gt; to tell cmake it should run a particular command with given parameters. If it returns zero, it succeeded. You can use it to simply run a testrunner binary or to make a matrix of input parameters that are expected to not crash the program.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cmake_minimum_required ( VERSION 3.26 )

project ( testrunner )
add_executable ( ${PROJECT_NAME} Main.cpp )

enable_testing()
add_test(
   NAME &quot;Example with no params&quot;
   COMMAND ${PROJECT_NAME}
)

add_test(
   NAME &quot;Example with help param&quot;
   COMMAND ${PROJECT_NAME} -h
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order to &lt;code&gt;add_test&lt;/code&gt; do anything, one has to also call &lt;code&gt;enable_testing()&lt;/code&gt;. Running the tests is just a matter of running ctest from command line. Just note that ctest requires you to specify a build configuration if you have more than one.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=4332370757284522768&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/15918/tuesday-coding-tip-10-ctest</guid>
<pubDate>Tue, 05 May 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 09 — Source location</title>
<link>https://coderlegion.com/15917/tuesday-coding-tip-09-source-location</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If you want to log a filename and line number prior to C++20, you need to use the likes of &lt;code&gt;__FILE__&lt;/code&gt; and &lt;code&gt;__LINE__&lt;/code&gt; macros. To use those easily, you have to create a wrapper macro for logging, which usually leads to an ugly macro bonanza.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;format&amp;gt;

void log(
    const std::string&amp;amp; message,
    const std::string&amp;amp; fileName = __FILE__,
    unsigned lineNo = __LINE__)
{
    std::cout &amp;lt;&amp;lt; std::format(
        &quot;{}({}): {}\n&quot;,
        fileName,
        lineNo,
        message);
}

#define LOG(msg) log(msg, __FILE__, __LINE__)

int main()
{
    log(&quot;hello world&quot;);
    // logs: example.cpp(7): hello world
    // Note that __FILE__ and __LINE__ are expanded at their
    // position, not at the callsite
    LOG(&quot;hello world2&quot;);
    // logs: example.cpp(22): hello world2
    // Wrapping the call in another macro with explicit placement
    // of __FILE__ and __LINE__ makes them expand at the correct place
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C++20 introduces &lt;code&gt;std::source_location&lt;/code&gt;, a regular object that can be constructed as a default value of a logging function parameter and passed along as the user needs.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;source_location&amp;gt;
#include &amp;lt;format&amp;gt;

void log(
    const std::string&amp;amp; message,
    std::source_location location = std::source_location::current())
{
    std::cout &amp;lt;&amp;lt; std::format(
        &quot;{}({}) {}: {}\n&quot;,
        location.file_name(),
        location.line(),
        location.function_name(),
        message);
}

int main()
{
    log(&quot;hello world&quot;);
    // logs: example.cpp(19) int main(): hello world
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/15917/tuesday-coding-tip-09-source-location</guid>
<pubDate>Tue, 28 Apr 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 08 — Explicit template specialization</title>
<link>https://coderlegion.com/14710/tuesday-coding-tip-08-explicit-template-specialization</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;While template instantiation can be used to move your template implementation from header files to object files for a given subset of types, specialization allows you to override the default template implementation for a particular type.&lt;/p&gt;
&lt;p&gt;Specialization requires that you first define the template implementation and then you can implement any number of specializations for given types. This way, you can override free functions (while maintaining their overall signature) or you can override whole classes (and you don’t have to respect their interfaces). This way, you can create drop-in replacements for library containers specialized for particular types and try to optimize them for your use case.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;filesystem&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

template&amp;lt;class T&amp;gt;
T concat(T a, const T&amp;amp; b)
{
    return a + b;
}

namespace fs = std::filesystem;

fs::path concat(fs::path a, const fs::path&amp;amp; b)
{
    return a / b;
}

int main()
{
    using namespace std::string_literals;
    std::cout &amp;lt;&amp;lt; concat(&quot;aaa&quot;s, &quot;bbb&quot;s) &amp;lt;&amp;lt; std::endl;        // outputs: aaabbb
    std::cout &amp;lt;&amp;lt; concat(&quot;aaa&quot;, &quot;bbb&quot;).string() &amp;lt;&amp;lt; std::endl; // outputs: aaa\bbb
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The specialization can also be partial and it can be &lt;code&gt;inline&lt;/code&gt;/&lt;code&gt;const&lt;/code&gt; whatever even if the original template is not.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

template&amp;lt;class T&amp;gt;
struct CustomType
{
    T foo() { return T {}; }
};

template&amp;lt;&amp;gt;
struct CustomType&amp;lt;std::string&amp;gt;
{
    std::string bar() { return &quot;hello world&quot;; }
};

int main()
{
    CustomType&amp;lt;int&amp;gt; ct1;
    std::cout &amp;lt;&amp;lt; ct1.foo() &amp;lt;&amp;lt; std::endl; // outputs: 0
    CustomType&amp;lt;std::string&amp;gt; ct2;
    std::cout &amp;lt;&amp;lt; ct2.bar() &amp;lt;&amp;lt; std::endl; // outputs: &quot;hello world&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Last but not least, if you’re implementing a template and need to change only a few lines of implementation for one particular type, you don’t need specialization. Instead, use &lt;code&gt;constexpr&lt;/code&gt; conditions — they are evaluated in compile time and optimized away when the compiler emits its own specialized code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;concepts&amp;gt;
#include &amp;lt;filesystem&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

template&amp;lt;class T&amp;gt;
T concat(T a, const T&amp;amp; b)
{
    if constexpr (std::is_same_v&amp;lt;T, std::filesystem::path&amp;gt;)
        return a / b;
    else
        return a + b;
}

int main()
{
    using namespace std::string_literals;
    using path = std::filesystem::path;
    std::cout &amp;lt;&amp;lt; concat(&quot;aaa&quot;s, &quot;bbb&quot;s) &amp;lt;&amp;lt; std::endl; // outputs: aaabbb
    std::cout &amp;lt;&amp;lt; concat(path{ &quot;aaa&quot; }, path{ &quot;bbb&quot; }).string()
              &amp;lt;&amp;lt; std::endl; // outputs: aaa\bbb
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14710/tuesday-coding-tip-08-explicit-template-specialization</guid>
<pubDate>Tue, 21 Apr 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 06 - Explicit template instantiation</title>
<link>https://coderlegion.com/13658/tuesday-coding-tip-06-explicit-template-instantiation</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Templated code in C++ must be defined in the header files (or a function within the same &lt;code&gt;.cpp&lt;/code&gt; file). This is because whenever a templated function is called, the compiler generates a new implementation using the concrete type the function was called with. If you split the definition from the declaration, you need to tell it what implementations to generate and link.&lt;/p&gt;
&lt;p&gt;That’s what explicit template instantiation is for. It is useful when you’re writing generic code for a well-known subset of types, like string manipulation. It cannot be used for totally generic types because you need to be able to list all types the template will be used with (otherwise the user will get a linker error).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// .hpp
#pragma once

#include &amp;lt;string&amp;gt;
#include &amp;lt;concepts&amp;gt;

// Note me using constructible_from instead of is_same_v. This will
// get me into trouble
template&amp;lt;class T&amp;gt;
concept NarrowOrWideString = std::constructible_from&amp;lt;std::string, T&amp;gt;
|| std::constructible_from&amp;lt;std::wstring, T&amp;gt;;

template&amp;lt;NarrowOrWideString StringType&amp;gt;
StringType StrTransformation(StringType source);

template&amp;lt;NarrowOrWideString StringType&amp;gt;
class ClassTemplate
{
public:
    static StringType StrTransformation(StringType source);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// .cpp
template&amp;lt;NarrowOrWideString StringType&amp;gt;
StringType StrTransformation&amp;lt;StringType&amp;gt;(StringType source)
{
   /* some transformation */
   return source;
}

template std::string StrTransformation&amp;lt;std::string&amp;gt;(std::string);
template std::wstring StrTransformation&amp;lt;std::wstring&amp;gt;(std::wstring);


template&amp;lt;NarrowOrWideString StringType&amp;gt;
StringType ClassTemplate&amp;lt;StringType&amp;gt;::StrTransformation(StringType source)
{
   /* some transformation */
   return source;
}

template class ClassTemplate&amp;lt;std::string&amp;gt;;
template class ClassTemplate&amp;lt;std::wstring&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// main.cpp
int main()
{
   {
      // This links, note the explicitly created string in parameters
      auto str = StrTransformation(std::string(&quot;aaa&quot;));
    
      auto wstr = StrTransformation(std::wstring(L&quot;bbb&quot;));
    
      // ERROR: Type does not conform to concept
      // auto num = StrTransformation(10);
    
      // ERROR: Type does conform to concept,
      // but template was not instantiated for const char[4]
      // auto str2 = StrTransformation(&quot;aaa&quot;);
    
      // This works, template overload was explicitly specified
      // and the concept allows conversion of const char* to std::string
      // Note that if I used is_same_v instead of constructible_from,
      // I couldn't use const char* as an argument.
      auto str3 = StrTransformation&amp;lt;std::string&amp;gt;(&quot;aaa&quot;);
    
      // Or I can make an alias
      constexpr auto&amp;amp;&amp;amp; StrTransformationA = StrTransformation&amp;lt;std::string&amp;gt;;
      auto str4 = StrTransformationA(&quot;aaa&quot;);
   }
  
   {
      // ERROR: C++ template type deduction is not good enough
      // auto str1 = ClassTemplate::StrTransformation(std::string(&quot;aaa&quot;));
    
      // I need to be explicit
      auto str2 = ClassTemplate&amp;lt;std::string&amp;gt;::StrTransformation(&quot;aaa&quot;);
    
      // Or make an alias
      using ClassTemplateA = ClassTemplate&amp;lt;std::string&amp;gt;;
      auto str3 = ClassTemplateA::StrTransformation(&quot;aaa&quot;);
   }
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/13658/tuesday-coding-tip-06-explicit-template-instantiation</guid>
<pubDate>Tue, 07 Apr 2026 09:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 05 - Object initialization in C++</title>
<link>https://coderlegion.com/13657/tuesday-coding-tip-05-object-initialization-in-c</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;There is a five-hundred-page book about C++ initialization out there. Why? Because we cater to way too many styles and many constructor capabilities. This tip is not about explaining all the options but rather about some good practices you can use to minimize mistakes.&lt;/p&gt;
&lt;p&gt;The “classic” or pre-C++11 way of initializing objects has the pitfall of triggering the “most vexing parse”. In such case, the compiler cannot tell whether you are calling a constructor or making a function declaration. And because C allowed for function declaration inside functions, it will pick the function declaration. You can omit the braces for the default constructor, but you can still encounter problems as shown in the ‘mvp2’ case. Trunk versions of GCC and Clang emit a helpful warning in this case.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Classic C++ style
Object obj1(param1, param2); // This works
Object mvp1(); // Most Vexing Parse
Object mvp2(int(param1), int(param2)); // Also MVP
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The “modern”, “universal” or post-C++11 way is also not the best one. It is consistent with struct initialization but can invoke incorrect constructors if you intermix normal parameters and &lt;code&gt;std::initializer_list&lt;/code&gt; as demonstrated with the &lt;code&gt;std::vector&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Modern (uniform) C++ style
Object obj2{param1, param2};
Object obj2_2 = {param1, param2};
std::vector&amp;lt;int&amp;gt; vec(10); // vector containing ten default constructed items
std::vector&amp;lt;int&amp;gt; vec{10}; // vector containing one element with value 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you have what I call a “Java” style. It’s verbose and has the same issues if you use curly braces. At least it doesn’t trigger MVP. The last version is what I often use due to its similarity to many other languages where you use &lt;code&gt;var&lt;/code&gt; or &lt;code&gt;let&lt;/code&gt; to denote the variables and usually specify the type name after the variable name.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Verbose Java style
Object obj3 = Object(param1, param2);
Object obj3_2 = Object{param1, param2};

// Modern language style
auto obj4 = Object(param1, param2);
auto obj4_2 = Object{param1, param2};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that even though there is an assignment operator, no assignment, copy or move is happening — objects are constructed directly.&lt;/p&gt;
&lt;p&gt;I recommend using the “modern language style” with simple braces only for regular constructors and curly braces only for initializer-list constructors. It makes your intent clear and prevents you from accidentally shooting yourself in the foot. “Java style” might be preferable for class attribute declarations, with the same rules regarding braces.&lt;/p&gt;
&lt;p&gt;More on the subject:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.youtube.com/watch?v=7DTlWPgX6zs&quot;&gt;CppCon 2018: Nicolai Josuttis “The Nightmare of Initialization in C++” — YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://stackoverflow.com/questions/49802012/different-ways-of-initializing-an-object-in-c&quot;&gt;class — Different ways of initializing an object in c++ — Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/13657/tuesday-coding-tip-05-object-initialization-in-c</guid>
<pubDate>Tue, 31 Mar 2026 09:26:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 04 - Precompiled headers</title>
<link>https://coderlegion.com/12876/tuesday-coding-tip-04-precompiled-headers</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Do you use CMake and need to improve your C++ compile times? There’s a technique called precompiled headers. Usually, it is somewhat obtuse to set up, MSVC tends to force you to include the precompiled header in every single &lt;code&gt;.cpp&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;With CMake, you can use a single command to instantly boost your compile times with zero invasiveness. On my hobby project, I reduced compile time down from 3m30s to just 30s (in single threaded CI, I went from 7m to 3m30s).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# PROJECT_NAME refers to target that was used with
# add_library or add_executable command
target_precompile_headers ( ${PROJECT_NAME}
    PRIVATE
        &amp;lt;vector&amp;gt;
        &amp;lt;format&amp;gt;
        &amp;lt;map&amp;gt;
        &amp;lt;unordered_map&amp;gt;
        &amp;lt;array&amp;gt;
        &amp;lt;optional&amp;gt;
        &amp;lt;expected&amp;gt;
        &amp;lt;fstream&amp;gt;
        &amp;lt;filesystem&amp;gt;
        &amp;lt;functional&amp;gt;
        &amp;lt;concepts&amp;gt;
        &amp;lt;memory&amp;gt;
        &amp;lt;string&amp;gt;
        &amp;lt;cstdint&amp;gt;
        &amp;lt;DGM/dgm.hpp&amp;gt;
        &amp;lt;TGUI/tgui.hpp&amp;gt;
        &amp;lt;json.hpp&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just remember to only include headers that don’t change often, presumably never. Good candidates are &lt;code&gt;std&lt;/code&gt; headers and third party header-only dependencies.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12876/tuesday-coding-tip-04-precompiled-headers</guid>
<pubDate>Tue, 24 Mar 2026 10:59:00 +0000</pubDate>
</item>
<item>
<title>Error does not name a type C++</title>
<link>https://coderlegion.com/13363/error-does-not-name-a-type-c</link>
<description>&lt;h1&gt; Error does not name a type in C++
&lt;/h1&gt;
&lt;p&gt;The &quot;error does not name a type&quot; in C/C++ is defined as the when user declares outside of the function or does not include it properly in the main file this error will through.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/dtVS0znp/image.png&quot; alt=&quot;&quot; width=&quot;639&quot; height=&quot;359&quot;&gt;&lt;/p&gt;
&lt;h5 class=&quot;pk-title pk-toc-title pk-font-block&quot;&gt;TABLE OF CONTENTS&lt;/h5&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#what-is-attributeerror-module-object-has-no-attribute-strptime&quot;&gt;Why this error occurs?&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#how-to-resolve&quot;&gt;How to resolve:&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#solution-1-use-local-web-server&quot;&gt;Solution 1:&lt;/a&gt;


&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#solution-1-use-local-web-server1&quot;&gt;Solution 2:&lt;/a&gt;

&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#solution-3-use-local-web-server1&quot;&gt;Solution 3:&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;what-is-attributeerror-module-object-has-no-attribute-strptime&quot;&gt;&lt;strong&gt;Why this error occurs?&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;File: sample.h  
 #ifndef SAMPLE_H__&amp;lt;br /&amp;gt;#define SAMPLE_H__
   namespace Sampletest {
    class CP_M_ReferenceCounted&amp;lt;br /&amp;gt;{&amp;lt;br /&amp;gt;};
    }
    #endif
    &amp;lt;br /&amp;gt;File : test.cpp
#include &quot;sample.h&quot;
    typedef CP_M_ReferenceCounted FxRC;
   &amp;lt;br /&amp;gt;int main(int argc, char **argv)&amp;lt;br /&amp;gt;{
    &amp;lt;p&amp;gt;return 0;&amp;lt;br /&amp;gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;If you run the above code you will get the error &quot;...error: CP_M_ReferenceCounted does not name a type&quot;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h2 id=&quot;how-to-resolve&quot;&gt;&lt;strong&gt;How to resolve :&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;To overcome this error follow this two methods of solutions&lt;/p&gt;
&lt;h2 id=&quot;solution-1-use-local-web-server&quot; style=&quot;line-height: 1;&quot;&gt;&lt;strong&gt;Solution 1:&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;To avoid this error, we have to add the &quot;using namespace Sampletest&quot; at the start of the program in C++.&lt;/p&gt;
&lt;p&gt;To avoid this error, we have to add the &quot;using namespace Sampletest&quot; at the start of the program in C++.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;File : test.cpp&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;#include &quot;sample.h&quot;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;//Add the following to your code&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;using namespace Sampletest&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;typedef CP_M_ReferenceCounted FxRC;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;br /&amp;gt;int main(int argc, char **argv)&amp;lt;br /&amp;gt;{&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;return 0;&amp;lt;br /&amp;gt;}&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;solution-1-use-local-web-server1&quot; style=&quot;line-height: 1;&quot;&gt;&lt;strong&gt;Solution 2:&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;To avoid this kind of error we need to add the header &quot;#include sample.h&quot; at the starting of the program in C++.&lt;/p&gt;
&lt;p&gt;Same Problem while declaring outside of the function&lt;/p&gt;
&lt;p&gt;These kinds of errors are also acquired while printing outside of any function.&lt;br&gt;A statement which isn't declaration in C++ need to be printed inside of the function&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;b&gt;File test.cpp&lt;/b&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;#include &amp;lt;iostream&amp;gt;&amp;lt;br /&amp;gt;#include &amp;lt;cstring&amp;gt;&amp;lt;br /&amp;gt;using namespace std;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;struct Node{&amp;lt;br /&amp;gt;char *name;&amp;lt;br /&amp;gt;int age;&amp;lt;br /&amp;gt;Node(char *nc = &quot;&quot;, int ax = 0){&amp;lt;br /&amp;gt;name = new char[strlen(nc) + 1];&amp;lt;br /&amp;gt;strcpy(name, n);&amp;lt;br /&amp;gt;age = ax;&amp;lt;br /&amp;gt;}&amp;lt;br /&amp;gt;};&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Node node1(&quot;Roger&quot;, 20), node2(node1);&amp;lt;br /&amp;gt;cout &amp;lt;&amp;lt; node1.name &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node1.age &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node2.name &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node2.age;&amp;lt;br /&amp;gt;strcpy(node2.name, &quot;Wendy&quot;);&amp;lt;br /&amp;gt;node2.name = 30;&amp;lt;br /&amp;gt;cout &amp;lt;&amp;lt; node1.name &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node1.age &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node2.name &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node2.age;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt; &amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;Output :&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;error: ‘node2’ does not name a type&amp;lt;/p&amp;gt;
&amp;lt;br/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;solution-3-use-local-web-server1&quot; style=&quot;line-height: 1;&quot;&gt;&lt;strong&gt;Solution 3:&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;To avoid these types of errors you need to add everything inside the function,&lt;br&gt;because a statement that isn't a declaration in C++ needs to be inside the function&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;p&amp;gt;&amp;lt;code&amp;gt;int main() {&amp;lt;br /&amp;gt;Node node1(&quot;Roger&quot;, 20), node2(node1);&amp;lt;br /&amp;gt;cout &amp;lt;&amp;lt; node1.name &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node1.age &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node2.name &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node2.age;&amp;lt;br /&amp;gt;strcpy(node2.name, &quot;Wendy&quot;);&amp;lt;br /&amp;gt;node2.name = 30;&amp;lt;br /&amp;gt;cout &amp;lt;&amp;lt; node1.name &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node1.age &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node2.name &amp;lt;&amp;lt; ' ' &amp;lt;&amp;lt; node2.age;&amp;lt;br /&amp;gt;}&amp;lt;/code&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;conclusion&quot; style=&quot;text-align: left;&quot;&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;In this article, we have seen why the undefined error occurs in C/C++ and discussed how to resolve these errors in various methods.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/13363/error-does-not-name-a-type-c</guid>
<pubDate>Mon, 23 Mar 2026 09:40:17 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 03 - Structured bindings</title>
<link>https://coderlegion.com/12874/tuesday-coding-tip-03-structured-bindings</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Since C++17, we can use “structured bindings”. These allow you to perform tuple, array, or even structure unpacking. Such unpacking is commonly helpful when iterating over maps, so you don’t have to define an alias for key and value manually. It is equally useful when a function returns a tuple.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;// Iterating over key-value pairs
auto myMap = std::unordered_map&amp;lt;std::string, int&amp;gt;{ /* ... */ };
for (auto&amp;amp;&amp;amp; [key, value] : myMap)
{ /* ... */ }

// Tuple unpacking
auto&amp;amp;&amp;amp; [index, quantity, name] = std::tuple{10, 30, &quot;a&quot;};

// Struct member aliasing
struct S {
    int veryLongAndDescriptiveName;
    std::string anotherVeryWordyName;
};

auto&amp;amp;&amp;amp; [index2, name2] = S{}; // s is of type S

// Array unpacking
auto&amp;amp;&amp;amp; [first, second, third] = std::array{1, 2, 3};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unpacking struct members and arrays is just a cherry on top. You won’t use it much, but it is there should you ever need it!&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12874/tuesday-coding-tip-03-structured-bindings</guid>
<pubDate>Tue, 17 Mar 2026 10:59:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 02 - Template with type-specific API</title>
<link>https://coderlegion.com/12272/tuesday-coding-tip-02-template-with-type-specific-api</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;What if you had a template class and you wanted to give it extra methods for certain specializations?&lt;/p&gt;
&lt;p&gt;For example, you might want to make a templated initialization guard and you want it to be as non-intrusive as possible. So you want it to support arithmetic operations if the underlying type is an arithmetic type.&lt;/p&gt;
&lt;p&gt;Before C++20, you could leverage &lt;code&gt;std::enable_if&lt;/code&gt;. However, such code is clunky and unreadable:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;type_traits&amp;gt;
#include &amp;lt;string&amp;gt;

// Pre C++20
template&amp;lt;class T&amp;gt;
class TemplatedClass
{
public:
  template&amp;lt;class = typename std::enable_if&amp;lt;std::is_integral&amp;lt;T&amp;gt;::value&amp;gt;::type&amp;gt;
  void foo() {}
};

int main()
{
  TemplatedClass&amp;lt;int&amp;gt; a;
  a.foo(); // OK

  TemplatedClass&amp;lt;std::string&amp;gt; b;
  b.foo(); /* Error:
  error: failed requirement 'std::is_integral&amp;lt;std::basic_string...&amp;gt;' requested here
  error: no matching member function for call to 'foo'
  note: candidate template ignored: couldn't infer template argument ''
  */
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With C++20, you can use concepts and the requires keyword to clean up the syntax significantly, either by in-place definition of type properties or by defining a dedicated concept. It also improves readability of error messages.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;type_traits&amp;gt;
#include &amp;lt;string&amp;gt;

// C++20, requires
template&amp;lt;class T&amp;gt;
class TemplatedClass2
{
public:
  template&amp;lt;typename = void&amp;gt;
  requires std::is_integral_v&amp;lt;T&amp;gt;
  void foo() {}
};

// C++20 with concept
template&amp;lt;class T&amp;gt;
concept IsIntegral = std::is_integral_v&amp;lt;T&amp;gt;;

template&amp;lt;class T&amp;gt;
class TemplatedClass3
{
public:
  template&amp;lt;typename = void&amp;gt;
  requires IsIntegral&amp;lt;T&amp;gt;
  void foo() {}
};

int main() {
  TemplatedClass2&amp;lt;int&amp;gt; a;
  a.foo(); // Ok

  TemplatedClass3&amp;lt;std::string&amp;gt; b;
  b.foo(); /* Error:
  error: no matching member function for call to 'foo'
  note: candidate template ignored: constraints not satisfied [with $0 = void]
  note: because 'std::basic_string&amp;lt;char&amp;gt;' does not satisfy 'IsIntegral'
  note: because 'std::is_integral_v&amp;lt;std::basic_string&amp;lt;char&amp;gt; &amp;gt;' evaluated to false
  */
}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12272/tuesday-coding-tip-02-template-with-type-specific-api</guid>
<pubDate>Tue, 10 Mar 2026 11:00:00 +0000</pubDate>
</item>
<item>
<title>Tuesday Coding Tip 01 - C++ Concepts</title>
<link>https://coderlegion.com/12271/tuesday-coding-tip-01-c-concepts</link>
<description>&lt;p&gt;Tuesday coding tips are super short posts about various tidbits mainly from C++, but also from other programming languages I use. You can also follow the #TuesdayCodingTips hashtag on Mastodon and Linkedin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Concepts are a C++20 feature that greatly simplifies templated code and allows you to build powerful type trait restrictions.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;concepts&amp;gt;

class Interface {
public:
    ~Interface() = default;
};

template&amp;lt;class T&amp;gt;
concept DerivedFromInterface = std::derived_from&amp;lt;T, Interface&amp;gt;;

// Note how 'class' or 'typename' is replaced with 'DerivedFromInterface'
template&amp;lt;DerivedFromInterface ObjectType&amp;gt;
void DoSomethingWith(ObjectType&amp;amp; object) {}

// Usage
class A final : public Interface {};
A a;
DoSomethingWith(a);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, you can create a function that accepts a concrete type that implements a certain interface, potentially allowing the compiler to optimize away the virtual table. Or you can define static interfaces where an object is required to have certain methods or even attributes, even if it doesn’t implement any inheritance-based interface. Or you can restrict the function to be called only with a small subset of well-known types.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;concepts&amp;gt;
#include &amp;lt;string&amp;gt;

template&amp;lt;class T&amp;gt;
concept Serializable = requires(T&amp;amp;&amp;amp; object)
{
    // Object has callable method 'serialize' which
    // returns something that works same as std::string
    { object.serialize()} -&amp;gt; std::same_as&amp;lt;std::string&amp;gt;;
};

template&amp;lt;Serializable T&amp;gt;
void UploadSerializable(const T&amp;amp; object)
{
    auto data = object.serialize();
    // ...
}

// Usage
class Settings {
public:
    std::string serialize() const { return &quot;&quot;; }
};

Settings settings;
UploadSerializable(settings);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Concepts do not replace dynamic polymorphism as you cannot do everything in compile-time. Still, it can open new optimization opportunities and help you write in-place construction functions like &lt;code&gt;std::make_unique&lt;/code&gt; without an excessive amount of unreadable templates.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;concepts&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;memory&amp;gt;

// A function that accepts any string, disregarding if wide or narrow
template&amp;lt;typename T&amp;gt;
requires std::is_same_v&amp;lt;T, std::string&amp;gt; || std::is_same_v&amp;lt;T, std::wstring&amp;gt;
void DoSomethingWithAString(const T&amp;amp; str) {}

// A better implementation of make_unique which checks whether the
// object can be created from given arguments
template&amp;lt;class T, class ... Args&amp;gt;
requires std::constructible_from&amp;lt;T, Args...&amp;gt;
std::unique_ptr&amp;lt;T&amp;gt; make_unique(Args&amp;amp;&amp;amp; ... args)
{
    return std::unique_ptr&amp;lt;T&amp;gt;(new T(std::forward&amp;lt;Args&amp;gt;(args)...));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, among the benefits to the syntax, they improve the compiler error messages, making life of your users way simpler.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12271/tuesday-coding-tip-01-c-concepts</guid>
<pubDate>Tue, 03 Mar 2026 11:00:00 +0000</pubDate>
</item>
<item>
<title>std::visit is awesome, here’s why</title>
<link>https://coderlegion.com/11855/std-visit-is-awesome-heres-why</link>
<description>&lt;p&gt;One of the very few features of the C++ standard library that I unapologetically like, is the &lt;code&gt;std::visit&lt;/code&gt;. It reduces the amount of boilerplate code, kills multiple birds with a single stone, and doesn’t sacrifice performance while doing it. So let’s have a look at how to use it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;visitor-pattern&quot;&gt;Visitor pattern&lt;/h2&gt;
&lt;p&gt;The Visitor pattern is a more complex OOP design pattern, but once you understand it, it becomes a great tool for breaking up dependencies and removing obtuse conditional statements with RTTI.&lt;/p&gt;
&lt;p&gt;It allows you to separate data structures from algorithms operating on those data structures, making it easier to add new algorithms or alter the structures without having to redeploy the other half.&lt;/p&gt;
&lt;p&gt;It is popular in compilers, where your source code is represented by an abstract syntax tree (AST), and every single optimization or analysis, like constant propagation, expression folding, or precondition analysis is implemented as its own class (so-called Visitor), separately from the AST declaration.&lt;/p&gt;
&lt;p&gt;If you’d like to know how to implement Visitor from the ground up, look no further than &lt;a rel=&quot;nofollow&quot; href=&quot;https://refactoring.guru/design-patterns/visitor&quot;&gt;superb refactoring.guru website&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;without-inheritance&quot;&gt;Without inheritance&lt;/h3&gt;
&lt;p&gt;Unlike the standard object-oriented implementation of the Visitor pattern, &lt;code&gt;std::visit&lt;/code&gt; doesn’t require you to use inheritance. Due to the underlying use of &lt;code&gt;std::variant&lt;/code&gt; and dark standard library magic, &lt;code&gt;std::visit&lt;/code&gt; doesn’t use double dispatch and thus you don’t need any accept method on your data structures:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;variant&amp;gt;
#include &amp;lt;vector&amp;gt;

struct NodeA {};
struct NodeB {};
struct NodeC {};

using Nodes = std::variant&amp;lt;NodeA, NodeB, NodeC&amp;gt;;

struct Visitor {
    void operator() (const NodeA&amp;amp;) { std::cout &amp;lt;&amp;lt; &quot;NodeA&quot; &amp;lt;&amp;lt; std::endl; }
    void operator() (const NodeB&amp;amp;) { std::cout &amp;lt;&amp;lt; &quot;NodeB&quot; &amp;lt;&amp;lt; std::endl; }
    void operator() (const NodeC&amp;amp;) { std::cout &amp;lt;&amp;lt; &quot;NodeC&quot; &amp;lt;&amp;lt; std::endl; }
};

int main() {
    std::vector&amp;lt;Nodes&amp;gt; nodes = {
        NodeA{},
        NodeB{},
        NodeA{},
        NodeC{}
    };

    for (auto&amp;amp;&amp;amp; node : nodes) std::visit(Visitor{}, node);

    // Prints:
    // NodeA
    // NodeB
    // NodeA
    // NodeC
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, all you need is a callable struct with overloads for required types. Note that you need to overload on all types that belong to &lt;code&gt;Nodes&lt;/code&gt; or you’ll get a compiler error (like with pattern matching in other languages).&lt;/p&gt;
&lt;p&gt;The error itself is a classic &lt;code&gt;std&lt;/code&gt; nonsense, so look out for this message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;no type named 'type' in 'std::invoke_result&amp;lt;Visitor, TypeThatIsMissing&amp;amp;&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;with-inheritance&quot;&gt;With inheritance&lt;/h3&gt;
&lt;p&gt;However, &lt;code&gt;std::visit&lt;/code&gt; allows using inheritance. That is even darker magic because you can, but don’t have to, add overloads for only some of the inherited types. The algorithm needs to be able to match the type on at least one overload, and the base class also applies:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;variant&amp;gt;
#include &amp;lt;vector&amp;gt;

struct NodeBase {};
struct NodeA : public NodeBase{};
struct NodeB : public NodeBase{};

using Nodes = std::variant&amp;lt;NodeA, NodeB&amp;gt;;

struct Visitor {
    void operator() (const NodeA&amp;amp;) { std::cout &amp;lt;&amp;lt; &quot;NodeA&quot; &amp;lt;&amp;lt; std::endl; }
    void operator() (const NodeBase&amp;amp;) { std::cout &amp;lt;&amp;lt; &quot;NodeBase&quot; &amp;lt;&amp;lt; std::endl; }
};

int main()
{
    std::vector&amp;lt;Nodes&amp;gt; nodes = {
        NodeA{},
        NodeB{},
    };

    for (auto&amp;amp;&amp;amp; node : nodes) std::visit(Visitor{}, node);

    // Prints:
    // NodeA
    // NodeBase
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The order of overloads doesn’t matter here. Specialization is preferred over the base class.&lt;/p&gt;
&lt;h3 id=&quot;faster-than-manual-dispatch&quot;&gt;Faster than manual dispatch&lt;/h3&gt;
&lt;p&gt;While &lt;code&gt;std::visit&lt;/code&gt; surely has a nice interface (a rare sight in the standard library) and it requires less boilerplate than implementing double dispatch manually, how’s the performance? I do have an unexpected answer - it is faster or at least as fast as the other solutions!&lt;/p&gt;
&lt;p&gt;I highly recommend watching Klaus Ingleberger’s talk about the Visitor pattern implementations where he also shows comparison times on &lt;a rel=&quot;nofollow&quot; href=&quot;https://youtu.be/PEcy1vYHb8A?t=2048&quot;&gt;GCC and Clang&lt;/a&gt; (timestamped to the part with the performance comparison). My own benchmarks on MSVC way back showed a clear win for &lt;code&gt;std::visit&lt;/code&gt; over other methods.&lt;/p&gt;
&lt;h2 id=&quot;functional-programming&quot;&gt;Functional programming&lt;/h2&gt;
&lt;p&gt;C++ committee often comments on how they like their proposals to kill multiple birds with one stone and in the notion of that mindset, you can use &lt;code&gt;std::visit&lt;/code&gt; functionally as well.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;variant&amp;gt;
#include &amp;lt;vector&amp;gt;

struct NodeA {};
struct NodeB {};

using Nodes = std::variant&amp;lt;NodeA, NodeB&amp;gt;;

template&amp;lt;class... Ts&amp;gt;
struct overloaded : Ts... { using Ts::operator()...; };

// Some compilers might require this explicit deduction guide
template&amp;lt;class... Ts&amp;gt;
overloaded(Ts...) -&amp;gt; overloaded&amp;lt;Ts...&amp;gt;;

int main()
{
    std::vector&amp;lt;Nodes&amp;gt; nodes = {
        NodeA{},
        NodeB{},
    };

    for (auto&amp;amp;&amp;amp; node : nodes) {
        std::visit(overloaded{
            [] (const NodeA&amp;amp;) { std::cout &amp;lt;&amp;lt; &quot;NodeA&quot; &amp;lt;&amp;lt; std::endl; },
            [] (const NodeB&amp;amp;) { std::cout &amp;lt;&amp;lt; &quot;NodeB&quot; &amp;lt;&amp;lt; std::endl; }
        }, node);
    }

    // Prints:
    // NodeA
    // NodeB
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of creating one dedicated visitor struct, you can use a helper template class to create an object out of a set of lambdas. This way, you can define your visiting code in the same place as you call it. Some people use this trick to emulate match statements from other languages, others might like it simply because it is functional programming.&lt;/p&gt;
&lt;h2 id=&quot;disadvantages&quot;&gt;Disadvantages&lt;/h2&gt;
&lt;p&gt;As noted by Klaus in his talk, every approach has its advantages and disadvantages. Because this approach is driven by the &lt;code&gt;std::variant&lt;/code&gt;, you must keep in mind its shortcomings:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Types need to be fully defined before they can be used in the variant. This is because their storage size needs to be known.&lt;/li&gt;
&lt;li&gt;Using types with vastly different sizes means that your variant will inherently waste a lot of space.&lt;/li&gt;
&lt;li&gt;Adding a new type might mean updating all existing visitors (not if you use inheritance) and updating the variant (which you don’t have to do with the classic OO approach).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Do note that you can address the first two problems by using wrapper types like smart pointers or employing the Pimpl pattern.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;As I said in the beginning, I like &lt;code&gt;std::visit&lt;/code&gt; very much. Implementing the Visitor pattern takes some getting used to and with this feature, you greatly reduce the amount of boilerplate, improve the readability of the code, and don’t sacrifice performance.&lt;/p&gt;
&lt;p&gt;Functional invocation is just a cherry on top for very localized usage where brand new class would just add noise to the code base.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/11855/std-visit-is-awesome-heres-why</guid>
<pubDate>Tue, 17 Feb 2026 22:55:13 +0000</pubDate>
</item>
<item>
<title>Unlocking Performance: How C++ Optimization Techniques in Compilers Outperform Python</title>
<link>https://coderlegion.com/3755/unlocking-performance-how-c-optimization-techniques-in-compilers-outperform-python</link>
<description>&lt;p&gt;C++ and Python are two popular programming languages that have distinct performance characteristics. C++ is a statically-typed, compiled language that is known for its efficiency and speed, while Python is a dynamically-typed, interpreted language that prioritizes ease of use and flexibility. One of the key factors that contribute to C++'s performance advantage is the optimization techniques employed by its compilers.&lt;/p&gt;
&lt;p&gt;C++ compilers, such as GCC and Clang, use a range of optimization techniques to generate efficient machine code. These techniques can be broadly categorized into several areas, including:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Instruction Selection and Scheduling&lt;/strong&gt;: C++ compilers can select the most efficient instructions for a given operation and schedule them to minimize dependencies and maximize parallelism. This can lead to significant performance improvements, particularly in compute-intensive applications.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Register Allocation&lt;/strong&gt;: C++ compilers can optimize the use of CPU registers to minimize memory accesses, which can significantly impact performance. By allocating registers efficiently, compilers can reduce the number of memory loads and stores, leading to faster execution times.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dead Code Elimination&lt;/strong&gt;: C++ compilers can eliminate code that is never executed, which can reduce the overall size of the program and improve performance. By removing unnecessary code, compilers can also reduce the number of cache misses and improve instruction-level parallelism.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Constant Folding and Propagation&lt;/strong&gt;: C++ compilers can evaluate constant expressions at compile-time and propagate the results, eliminating unnecessary runtime calculations. This can lead to significant performance improvements, particularly in applications that involve complex mathematical calculations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loop Optimization&lt;/strong&gt;: C++ compilers can optimize loops by techniques such as loop unrolling, loop fusion, and loop tiling. These optimizations can improve performance by reducing the overhead of loop control statements, improving cache locality, and increasing parallelism.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These optimization techniques can significantly contribute to C++'s performance advantage over Python. Python, being an interpreted language, does not have the same level of optimization opportunities as C++. While Python's interpreter can perform some optimizations, such as caching frequently executed code, it is generally limited by the dynamic nature of the language.&lt;/p&gt;
&lt;p&gt;One of the primary reasons why C++'s optimization techniques are more effective is that they are applied at compile-time, when the compiler has a complete view of the code and its dependencies. This allows the compiler to make informed decisions about optimization, such as which instructions to use, how to allocate registers, and how to schedule code.&lt;/p&gt;
&lt;p&gt;In contrast, Python's interpreter must make optimization decisions at runtime, based on the current state of the program. This can lead to less effective optimizations, as the interpreter may not have a complete view of the code and its dependencies.&lt;/p&gt;
&lt;p&gt;To illustrate the performance difference between C++ and Python, consider a simple example. Suppose we want to implement a program that performs a complex mathematical calculation, such as matrix multiplication.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Code:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;C++:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;

void matrixMultiply(int** A, int** B, int** C, int n) {
    for (int i = 0; i &amp;lt; n; i++) {
        for (int j = 0; j &amp;lt; n; j++) {
            C[i][j] = 0;
            for (int k = 0; k &amp;lt; n; k++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
}

int main() {
    int n = 1000;
    int** A = new int*[n];
    int** B = new int*[n];
    int** C = new int*[n];

    for (int i = 0; i &amp;lt; n; i++) {
        A[i] = new int[n];
        B[i] = new int[n];
        C[i] = new int[n];
    }

    // Initialize matrices A and B

    matrixMultiply(A, B, C, n);

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import numpy as np

def matrix_multiply(A, B):
    return np.matmul(A, B)

A = np.random.rand(1000, 1000)
B = np.random.rand(1000, 1000)

C = matrix_multiply(A, B)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, the C++ code uses manual memory management and loop optimizations to perform matrix multiplication, while the Python code uses the NumPy library to perform the same operation. While the Python code is easier to write and maintain, the C++ code is likely to be faster due to its manual memory management and loop optimizations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In conclusion, C++'s optimization techniques in compilers contribute significantly to its performance advantage over Python. By applying optimizations at compile-time, C++ compilers can generate efficient machine code that is tailored to the specific use case. While Python's interpreter can perform some optimizations, it is generally limited by the dynamic nature of the language.&lt;/p&gt;
</description>
<category>C++</category>
<guid isPermaLink="true">https://coderlegion.com/3755/unlocking-performance-how-c-optimization-techniques-in-compilers-outperform-python</guid>
<pubDate>Mon, 07 Jul 2025 02:08:59 +0000</pubDate>
</item>
<item>
<title>Why C++ Compilers Prefer Performance Over Safety Checks?</title>
<link>https://coderlegion.com/3375/why-c-compilers-prefer-performance-over-safety-checks</link>
<description>&lt;p&gt;C++ is a language synonymous with performance, control, and portability. For decades, it has powered the world's most demanding software systems, from operating systems to game engines and real-time trading platforms. At the heart of its power lies a controversial feature: undefined behavior (UB). This feature, or rather lack of behavior definition, has led to immense performance gains but also to programming pitfalls. When modern C++ compilers like GCC and Clang prioritize performance, they do so by aggressively assuming that undefined behavior never occurs. In this article, we will explore why these compilers make such design choices, the benefits and trade-offs involved, and how developers can harness these tools responsibly.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;1-the-c-design-philosophy-trust-the-programmer&quot;&gt;1. The C++ Design Philosophy: Trust the Programmer&lt;/h3&gt;
&lt;p&gt;One of the key tenets of C++ is that it &quot;trusts the programmer.&quot; This trust is not blind; it is intentional and foundational. Unlike languages like Java or Python that emphasize safety and abstraction, C++ offers low-level memory and hardware access. It does so while striving for zero-overhead abstractions. The premise is that a knowledgeable programmer can write highly efficient code if the compiler doesn't impose runtime safety checks that might slow execution.&lt;/p&gt;
&lt;h4 id=&quot;control-and-efficiency&quot;&gt;Control and Efficiency&lt;/h4&gt;
&lt;p&gt;C++ gives developers precise control over resource management. You decide how memory is allocated, how objects are constructed, and when resources are released. This fine-grained control enables performance tuning at a level unmatched by most high-level languages.&lt;/p&gt;
&lt;h4 id=&quot;no-built-in-safety-net&quot;&gt;No Built-in Safety Net&lt;/h4&gt;
&lt;p&gt;By default, C++ does not include bounds checking, null pointer validation, or automatic garbage collection. This lack of safety net is a double-edged sword. On one side lies blazing speed and fine control. On the other, the danger of undefined behavior.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;2-what-is-undefined-behavior-&quot;&gt;2. What is Undefined Behavior?&lt;/h3&gt;
&lt;p&gt;In the context of C++, undefined behavior refers to code that does not have a well-defined effect according to the C++ standard. When such code is executed, anything can happen. It may crash the program, produce unexpected results, or appear to work fine (only to break later).&lt;/p&gt;
&lt;h4 id=&quot;common-sources-of-ub&quot;&gt;Common Sources of UB&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Dereferencing null or dangling pointers&lt;/li&gt;
&lt;li&gt;Accessing array elements out of bounds&lt;/li&gt;
&lt;li&gt;Using uninitialized variables&lt;/li&gt;
&lt;li&gt;Violating strict aliasing rules&lt;/li&gt;
&lt;li&gt;Shifting integers by more than their width&lt;/li&gt;
&lt;li&gt;Modifying a variable more than once between sequence points&lt;/li&gt;
&lt;li&gt;Invoking functions through function pointers with the wrong signature&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are not bugs that merely produce wrong results; they allow the compiler to &lt;strong&gt;assume&lt;/strong&gt; they never happen.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;3-why-compilers-exploit-undefined-behavior&quot;&gt;3. Why Compilers Exploit Undefined Behavior&lt;/h3&gt;
&lt;p&gt;Both GCC and Clang are highly optimizing compilers. They use undefined behavior as a license to transform code under the assumption that such errors never occur. This leads to several advantages:&lt;/p&gt;
&lt;h4 id=&quot;a-dead-code-elimination&quot;&gt;a. Dead Code Elimination&lt;/h4&gt;
&lt;p&gt;Consider the following:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;if (ptr != nullptr) {
   *ptr = 10;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the compiler determines that &lt;code&gt;ptr&lt;/code&gt; is never null (or that dereferencing null is UB), it might remove the check entirely, resulting in more streamlined code.&lt;/p&gt;
&lt;h4 id=&quot;b-loop-optimizations&quot;&gt;b. Loop Optimizations&lt;/h4&gt;
&lt;p&gt;UB assumptions allow the compiler to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unroll loops&lt;/li&gt;
&lt;li&gt;Perform strength reduction&lt;/li&gt;
&lt;li&gt;Vectorize operations for SIMD instructions&lt;/li&gt;
&lt;li&gt;Parallelize independent iterations&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;c-constant-folding-and-propagation&quot;&gt;c. Constant Folding and Propagation&lt;/h4&gt;
&lt;p&gt;If a branch or operation leads to UB under certain conditions, compilers may discard it entirely or simplify control flow under the assumption that such branches are never taken.&lt;/p&gt;
&lt;h4 id=&quot;d-register-allocation-improvements&quot;&gt;d. Register Allocation Improvements&lt;/h4&gt;
&lt;p&gt;Assuming UB allows for more flexible reuse of registers, reducing memory access and increasing pipeline throughput.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;4-benefits-of-this-approach&quot;&gt;4. Benefits of This Approach&lt;/h3&gt;
&lt;h4 id=&quot;4-1-performance&quot;&gt;4.1 Performance&lt;/h4&gt;
&lt;p&gt;By ignoring checks and relying on the programmer's correctness, the compiler produces leaner, faster machine code. In performance-critical domains (e.g., embedded systems, high-frequency trading), even a 1-2% gain can be significant.&lt;/p&gt;
&lt;h4 id=&quot;4-2-simpler-compiler-internals&quot;&gt;4.2 Simpler Compiler Internals&lt;/h4&gt;
&lt;p&gt;When the compiler is allowed to assume certain operations never happen (like null pointer access), it simplifies the internal logic for code generation and optimization passes.&lt;/p&gt;
&lt;h4 id=&quot;4-3-portability&quot;&gt;4.3 Portability&lt;/h4&gt;
&lt;p&gt;This model ensures the same code can run efficiently across different platforms without runtime dependencies like garbage collectors or VM-based safety checks.&lt;/p&gt;
&lt;h4 id=&quot;4-4-greater-flexibility-for-developers&quot;&gt;4.4 Greater Flexibility for Developers&lt;/h4&gt;
&lt;p&gt;Developers who understand their system well can fine-tune performance and optimize memory usage, trading safety for precision when necessary.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;5-the-cost-dangerous-flexibility&quot;&gt;5. The Cost: Dangerous Flexibility&lt;/h3&gt;
&lt;h4 id=&quot;5-1-debugging-nightmares&quot;&gt;5.1 Debugging Nightmares&lt;/h4&gt;
&lt;p&gt;Because UB can manifest unpredictably, bugs are often hard to detect. Code that works on one compiler version may break on another. Debuggers might show misleading or inconsistent information when UB is triggered.&lt;/p&gt;
&lt;h4 id=&quot;5-2-security-vulnerabilities&quot;&gt;5.2 Security Vulnerabilities&lt;/h4&gt;
&lt;p&gt;Many buffer overflows and privilege escalation exploits originate from UB that goes unchecked during development. Attackers exploit these flaws to insert malicious code, steal data, or crash systems.&lt;/p&gt;
&lt;h4 id=&quot;5-3-non-deterministic-behavior&quot;&gt;5.3 Non-deterministic Behavior&lt;/h4&gt;
&lt;p&gt;A program might behave differently on each run or platform due to optimizations exploiting UB. This leads to issues in testing, especially in distributed or multithreaded applications.&lt;/p&gt;
&lt;h4 id=&quot;5-4-loss-of-portability&quot;&gt;5.4 Loss of Portability&lt;/h4&gt;
&lt;p&gt;Code relying unknowingly on UB may work on one architecture but fail on another. For example, pointer alignment or endianness assumptions may cause subtle and hard-to-detect issues.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;6-mitigation-strategies-for-developers&quot;&gt;6. Mitigation Strategies for Developers&lt;/h3&gt;
&lt;h4 id=&quot;6-1-use-static-analysis-tools&quot;&gt;6.1 Use Static Analysis Tools&lt;/h4&gt;
&lt;p&gt;Tools like &lt;code&gt;Clang-Tidy&lt;/code&gt;, &lt;code&gt;Cppcheck&lt;/code&gt;, and &lt;code&gt;Coverity&lt;/code&gt; help detect UB patterns in source code before runtime. They analyze control flow, memory access patterns, and data usage.&lt;/p&gt;
&lt;h4 id=&quot;6-2-enable-compiler-sanitizers&quot;&gt;6.2 Enable Compiler Sanitizers&lt;/h4&gt;
&lt;p&gt;Compiler sanitizers are invaluable for catching UB during testing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-fsanitize=undefined&lt;/code&gt;: Catches most UB issues like invalid casts or pointer arithmetic&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-fsanitize=address&lt;/code&gt;: Detects heap buffer overflows, use-after-free&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-fsanitize=thread&lt;/code&gt;: Catches race conditions in multithreaded programs&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-fsanitize=leak&lt;/code&gt;: Helps track memory leaks&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;6-3-adopt-safe-subsets&quot;&gt;6.3 Adopt Safe Subsets&lt;/h4&gt;
&lt;p&gt;Frameworks like MISRA-C++ or AUTOSAR C++ define subsets of the language that eliminate or constrain UB-prone features. These are essential in safety-critical industries like automotive and aerospace.&lt;/p&gt;
&lt;h4 id=&quot;6-4-use-modern-c-features&quot;&gt;6.4 Use Modern C++ Features&lt;/h4&gt;
&lt;p&gt;Prefer smart pointers (&lt;code&gt;std::unique_ptr&lt;/code&gt;, &lt;code&gt;std::shared_ptr&lt;/code&gt;), &lt;code&gt;std::optional&lt;/code&gt;, &lt;code&gt;std::variant&lt;/code&gt;, &lt;code&gt;std::array&lt;/code&gt; over raw pointers and C-style arrays. These features enforce safer access and clearer intent.&lt;/p&gt;
&lt;h4 id=&quot;6-5-enforce-code-reviews-and-testing&quot;&gt;6.5 Enforce Code Reviews and Testing&lt;/h4&gt;
&lt;p&gt;Robust peer reviews and extensive unit/integration testing help catch unintended UB before code reaches production.&lt;/p&gt;
&lt;h4 id=&quot;6-6-leverage-formal-verification-advanced-&quot;&gt;6.6 Leverage Formal Verification (Advanced)&lt;/h4&gt;
&lt;p&gt;For critical systems, formal methods can be used to prove the absence of UB under all conditions using mathematical techniques.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;7-why-not-just-eliminate-ub-&quot;&gt;7. Why Not Just Eliminate UB?&lt;/h3&gt;
&lt;p&gt;Eliminating undefined behavior would fundamentally change what C++ is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More runtime checks would degrade performance.&lt;/li&gt;
&lt;li&gt;It would become more like Java or Rust.&lt;/li&gt;
&lt;li&gt;Backward compatibility with decades of C/C++ code would break.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;UB is a deliberate, though controversial, part of the design. It is the price for raw power and flexibility.&lt;/p&gt;
&lt;p&gt;Languages like Rust take a different path: they eliminate most classes of UB at compile time through strict ownership and borrowing rules. But this comes at the cost of a steeper learning curve and more restrictive coding patterns.&lt;/p&gt;
&lt;p&gt;C++ allows expert programmers to write fast code with minimal abstraction costs, but the responsibility lies with the programmer to avoid UB through discipline and tooling.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;8-real-world-use-cases-embracing-ub-for-speed&quot;&gt;8. Real-World Use Cases Embracing UB for Speed&lt;/h3&gt;
&lt;h4 id=&quot;8-1-operating-systems&quot;&gt;8.1 Operating Systems&lt;/h4&gt;
&lt;p&gt;Linux kernel code is filled with performance-critical sections that rely on UB being carefully avoided but never checked. Kernel developers rely on strict coding guidelines and peer review to manage UB risk.&lt;/p&gt;
&lt;h4 id=&quot;8-2-game-engines&quot;&gt;8.2 Game Engines&lt;/h4&gt;
&lt;p&gt;Engines like Unreal Engine are written in C++ with heavy use of UB-ignoring constructs for maximum speed. Real-time rendering and physics engines must meet frame deadlines every few milliseconds.&lt;/p&gt;
&lt;h4 id=&quot;8-3-trading-systems&quot;&gt;8.3 Trading Systems&lt;/h4&gt;
&lt;p&gt;Low-latency trading platforms depend on compiler-optimized binaries where every nanosecond counts. Programmers in this domain carefully avoid UB through disciplined coding and extensive testing.&lt;/p&gt;
&lt;h4 id=&quot;8-4-embedded-systems&quot;&gt;8.4 Embedded Systems&lt;/h4&gt;
&lt;p&gt;In microcontrollers and IoT firmware, memory and processing power are limited. Developers must write tight, efficient code and often disable runtime checks, accepting the trade-offs of UB.&lt;/p&gt;
&lt;h4 id=&quot;8-5-scientific-simulations&quot;&gt;8.5 Scientific Simulations&lt;/h4&gt;
&lt;p&gt;High-performance computing (HPC) relies on C++ to run simulations on massive datasets. UB assumptions allow compilers to fully exploit hardware capabilities.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;9-compiler-flags-that-matter&quot;&gt;9. Compiler Flags That Matter&lt;/h3&gt;
&lt;p&gt;GCC and Clang both offer many flags to control optimization and UB behavior:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-O2&lt;/code&gt;, &lt;code&gt;-O3&lt;/code&gt;: Enable aggressive optimizations&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-fstrict-aliasing&lt;/code&gt;: Assumes pointers don’t alias unless explicitly cast&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-fno-strict-overflow&lt;/code&gt;: Prevents assuming signed integer overflow is UB&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-fsanitize=&lt;/code&gt;: Enables various runtime checks&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-Wall -Wextra&lt;/code&gt;: Turns on helpful warnings&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-pedantic&lt;/code&gt;: Enforces strict standard compliance&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;recommended-combinations&quot;&gt;Recommended Combinations&lt;/h4&gt;
&lt;p&gt;For development:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;g++ -O0 -g -fsanitize=undefined,address -Wall -Wextra
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For production:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;g++ -O3 -fstrict-aliasing -fomit-frame-pointer
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;10-conclusion-master-the-power-respect-the-danger&quot;&gt;10. Conclusion: Master the Power, Respect the Danger&lt;/h3&gt;
&lt;p&gt;C++ gives you a powerful toolset, but with it comes responsibility. GCC and Clang prioritize performance because that’s what the language promises: speed without overhead. Undefined behavior is not a mistake in the spec; it's a contract with the programmer. The compiler trusts you not to invoke UB, and in return, it gives you unmatched performance.&lt;/p&gt;
&lt;p&gt;To use C++ effectively:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understand the risks of undefined behavior&lt;/li&gt;
&lt;li&gt;Use the right tools to catch it early&lt;/li&gt;
&lt;li&gt;Write clean, testable, standards-compliant code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the world of systems programming, performance often trumps safety—but with the right knowledge and practices, you don’t have to choose between them.&lt;/p&gt;
&lt;h4 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h4&gt;
&lt;p&gt;While undefined behavior may seem like a flaw, it is in fact a feature that empowers developers to write some of the fastest code in the world. If used with care, and backed by tooling and discipline, it allows C++ to remain at the forefront of high-performance software engineering.&lt;/p&gt;
</description>
<category>C++</category>
<guid isPermaLink="true">https://coderlegion.com/3375/why-c-compilers-prefer-performance-over-safety-checks</guid>
<pubDate>Fri, 20 Jun 2025 09:24:12 +0000</pubDate>
</item>
</channel>
</rss>