Cursed arithmetic left shifts
So I recently came across a scenario where I needed to set a single bit in a 64 bit value. Simple:
uint64t result = 1ull << n;
I expected to rely on result being zero when n is out of range (n >= 64). Technically, this is how an arithmetic and logical shift would behave, according to their definitions as per wikipedia and technically intels x86 manual. Practically this is not how they behave on our hardware at all and I think this is interesting to share.
So I wrote this little test to see what happens when you shift out of range:
#include <iostream>
#include <bitset>
#include <stdint.h>
int main()
{
uint64t bitpattern = 0xF0FF0FF00FF0FF0Full;
// shift overflow
for (uint64t shift = 0;shift <= 128ull;shift++)
{
uint64t shiftresult = bitpattern << shift;
std::bitset<64> bitsetresult(shiftresult);
std::cout << bitsetresult << " for a shift of " << shift << std::endl;
}
return 0;
}
And right at the threshold to 64 the output does something funny:
1111000011111111000011111111000000001111111100001111111100001111 for a shift of 0
1110000111111110000111111110000000011111111000011111111000011110 for a shift of 1
1100001111111100001111111100000000111111110000111111110000111100 for a shift of 2
...
1110000000000000000000000000000000000000000000000000000000000000 for a shift of 61
1100000000000000000000000000000000000000000000000000000000000000 for a shift of 62
1000000000000000000000000000000000000000000000000000000000000000 for a shift of 63
1111000011111111000011111111000000001111111100001111111100001111 for a shift of 64
1110000111111110000111111110000000011111111000011111111000011110 for a shift of 65
1100001111111100001111111100000000111111110000111111110000111100 for a shift of 66
...
1100000000000000000000000000000000000000000000000000000000000000 for a shift of 126
1000000000000000000000000000000000000000000000000000000000000000 for a shift of 127
1111000011111111000011111111000000001111111100001111111100001111 for a shift of 128
It behaves as if
So, I did a little bit of digging and found that GCC uses the SAL instruction (arithmetic shift) to implement this. From what I gathered, when working with unsigned types the logical shift should be used but this is of no relevance as SAL and SHL are apparently equivalent on x86_64 machines (which I can confirm).
What is far more interesting is that these instructions seem to just ignore out of range shift operands. I guess CPU's are wired to siply just care about the bottom 6 significant digits (or 5 in the case of the 32 bit wide instruction equivalent, as this also happens with 32 bit values at n = 32.) Notably, it does not happen at n = 16 for 16 bit values, they still use the 32 bit range.
MSVC and clang both do insert an SHL (logical left shift) instead of a SAL but the result is the same.
Now, there is one thing that really tripped me when debugging this initially:
uint64t result = 0;
uint64t n = 63;
result = 1ull << (n + 1); // result is 1
result = 1ull << 64; // result is 0 !?
So, apparently, when GCC was able to just precompute the expression it would come up with the wrong result. This might be a compiler bug? This also happens on clang, I didn't test it on MSVC.
Just something I thought was interesting sharing. Took me quite a while to figure out what was happening and where my bug came from. It really stumped me for a day
https://redd.it/1ow3g9y
@r_cpp
So I recently came across a scenario where I needed to set a single bit in a 64 bit value. Simple:
uint64t result = 1ull << n;
I expected to rely on result being zero when n is out of range (n >= 64). Technically, this is how an arithmetic and logical shift would behave, according to their definitions as per wikipedia and technically intels x86 manual. Practically this is not how they behave on our hardware at all and I think this is interesting to share.
So I wrote this little test to see what happens when you shift out of range:
#include <iostream>
#include <bitset>
#include <stdint.h>
int main()
{
uint64t bitpattern = 0xF0FF0FF00FF0FF0Full;
// shift overflow
for (uint64t shift = 0;shift <= 128ull;shift++)
{
uint64t shiftresult = bitpattern << shift;
std::bitset<64> bitsetresult(shiftresult);
std::cout << bitsetresult << " for a shift of " << shift << std::endl;
}
return 0;
}
And right at the threshold to 64 the output does something funny:
1111000011111111000011111111000000001111111100001111111100001111 for a shift of 0
1110000111111110000111111110000000011111111000011111111000011110 for a shift of 1
1100001111111100001111111100000000111111110000111111110000111100 for a shift of 2
...
1110000000000000000000000000000000000000000000000000000000000000 for a shift of 61
1100000000000000000000000000000000000000000000000000000000000000 for a shift of 62
1000000000000000000000000000000000000000000000000000000000000000 for a shift of 63
1111000011111111000011111111000000001111111100001111111100001111 for a shift of 64
1110000111111110000111111110000000011111111000011111111000011110 for a shift of 65
1100001111111100001111111100000000111111110000111111110000111100 for a shift of 66
...
1100000000000000000000000000000000000000000000000000000000000000 for a shift of 126
1000000000000000000000000000000000000000000000000000000000000000 for a shift of 127
1111000011111111000011111111000000001111111100001111111100001111 for a shift of 128
It behaves as if
result = input << n % 64; !!So, I did a little bit of digging and found that GCC uses the SAL instruction (arithmetic shift) to implement this. From what I gathered, when working with unsigned types the logical shift should be used but this is of no relevance as SAL and SHL are apparently equivalent on x86_64 machines (which I can confirm).
What is far more interesting is that these instructions seem to just ignore out of range shift operands. I guess CPU's are wired to siply just care about the bottom 6 significant digits (or 5 in the case of the 32 bit wide instruction equivalent, as this also happens with 32 bit values at n = 32.) Notably, it does not happen at n = 16 for 16 bit values, they still use the 32 bit range.
MSVC and clang both do insert an SHL (logical left shift) instead of a SAL but the result is the same.
Now, there is one thing that really tripped me when debugging this initially:
uint64t result = 0;
uint64t n = 63;
result = 1ull << (n + 1); // result is 1
result = 1ull << 64; // result is 0 !?
So, apparently, when GCC was able to just precompute the expression it would come up with the wrong result. This might be a compiler bug? This also happens on clang, I didn't test it on MSVC.
Just something I thought was interesting sharing. Took me quite a while to figure out what was happening and where my bug came from. It really stumped me for a day
https://redd.it/1ow3g9y
@r_cpp
Reddit
From the cpp community on Reddit
Explore this post and more from the cpp community
Anyone else decided to ditch the baby with the bathwater and redesign C++ to fit their needs?
Really long story short, Ive had this idea in my head forever for a UEFI application, but I keep running into roadblocks actually trying to debug it whenever I try to implement it.
C is a little too old and really missing proper QOL features like templates, constructors, name scoping, etc.
Rust is great but I want to beat my face in with a rake dealing with memory allocations and the lifetime system
Zig is nearly perfect. not quite convinced on the build system yet but with better documentation, im sure ill be convinced. However, its impossible to output DWARF debug info for PE/COFF targets as is UEFI. Plus alot of the debugging features are broken in UEFI targets so actually finding bugs is near impossible.
So I got left with C++, after tasting the real freedom that is modern languages. Since UEFI is essentially a freestanding target anyway so I dont get stdlib support. So I figured fuck it, lets design a stdlib to fit my own needs.
#include <efi/typedef.h>
#include <efi/status.h>
#include <allocate.h>
#include <exit.h>
#include <QEMU/debugCon.h>
extern "C" Status efi_main(EFI_HANDLE ImageHandle, SystemTable* st, void* imageBase) {
Allocator iface = poolAllocator(st);
if (Option<Slice<char>> result = iface.alloc<char>(14); result.isSome()) {
Slice<char> str = result.unwrap();
const char* lit = "Hello World!\n";
for (uintmax_t i = 0; i < str.len; i++) {
str[i] = lit[i];
}
DebugCon::putChars(0, lit);
DebugCon::putChars(0, str.ptr);
iface.free(str);
}
return Status::Success;
}
After fighting with the compiler/linker for 2 weeks to get a bootable & debuggable image where UEFI, GDB, and the compiler wouldnt complain. I was finally able to write a CRT0 runtime, and modify the linker script for constructors/deconstructors. Then implement all the UEFI base types/definitions for a bare minimal environment and to properly handle debugging. Then I could start to implement core types like slice<t> and option<t> to handle things like memory allocations via a consumable interface.
Its been a rough several weeks, but im finally at the point where the "standard" library I will be using is starting to take enough shape. Just to make the above code run properly without bugs is \~2500 lines of code lol.
https://redd.it/1p7zlou
@r_cpp
Really long story short, Ive had this idea in my head forever for a UEFI application, but I keep running into roadblocks actually trying to debug it whenever I try to implement it.
C is a little too old and really missing proper QOL features like templates, constructors, name scoping, etc.
Rust is great but I want to beat my face in with a rake dealing with memory allocations and the lifetime system
Zig is nearly perfect. not quite convinced on the build system yet but with better documentation, im sure ill be convinced. However, its impossible to output DWARF debug info for PE/COFF targets as is UEFI. Plus alot of the debugging features are broken in UEFI targets so actually finding bugs is near impossible.
So I got left with C++, after tasting the real freedom that is modern languages. Since UEFI is essentially a freestanding target anyway so I dont get stdlib support. So I figured fuck it, lets design a stdlib to fit my own needs.
#include <efi/typedef.h>
#include <efi/status.h>
#include <allocate.h>
#include <exit.h>
#include <QEMU/debugCon.h>
extern "C" Status efi_main(EFI_HANDLE ImageHandle, SystemTable* st, void* imageBase) {
Allocator iface = poolAllocator(st);
if (Option<Slice<char>> result = iface.alloc<char>(14); result.isSome()) {
Slice<char> str = result.unwrap();
const char* lit = "Hello World!\n";
for (uintmax_t i = 0; i < str.len; i++) {
str[i] = lit[i];
}
DebugCon::putChars(0, lit);
DebugCon::putChars(0, str.ptr);
iface.free(str);
}
return Status::Success;
}
After fighting with the compiler/linker for 2 weeks to get a bootable & debuggable image where UEFI, GDB, and the compiler wouldnt complain. I was finally able to write a CRT0 runtime, and modify the linker script for constructors/deconstructors. Then implement all the UEFI base types/definitions for a bare minimal environment and to properly handle debugging. Then I could start to implement core types like slice<t> and option<t> to handle things like memory allocations via a consumable interface.
Its been a rough several weeks, but im finally at the point where the "standard" library I will be using is starting to take enough shape. Just to make the above code run properly without bugs is \~2500 lines of code lol.
https://redd.it/1p7zlou
@r_cpp
Reddit
From the cpp community on Reddit
Explore this post and more from the cpp community
what do you think about this
\#include <iostream>
\#define print(x) std::cout << x;
int main() {
char x[\] = " hello";
print("im dave," << x)
return 0;
}
can this be a problem?
https://redd.it/1p9owjg
@r_cpp
\#include <iostream>
\#define print(x) std::cout << x;
int main() {
char x[\] = " hello";
print("im dave," << x)
return 0;
}
can this be a problem?
https://redd.it/1p9owjg
@r_cpp
[Open Source] IACore: A battery-included C++20 foundation library (IPC, Async, HTTP, Logging) to escape dependency hell.
Hey friends,
Like many of you, I grew tired of "C++ Dependency Hell".. Every time I started a new project (specifically game engines and dev tools), I found myself wasting days setting up the same glue code: finding an HTTP library, setting up a job system, wrestling with platform-specific IPC, and configuring a logger.
I wanted a "bedrock" library—something I could drop into any project and immediately have the essentials working, without linking 50 different `.lib` files manually.
So I built **IACore**. It started as the internal core library for my work at **IASoft**, but I realized it solves a problem almost every C++ dev faces. I’ve cleaned it up, added tests, and I'm open-sourcing it under GPLv3 today.
**What's inside?** It wraps "best-in-class" dependencies into a unified, coherent C++20 API. It manages its own deps via CMake `FetchContent`, so you don't need to install anything manually.
* **⚡ IPC:** High-performance shared-memory ring buffers (wait-free SPSC).
* **🧵 Async:** A work-stealing job scheduler (High/Normal priority queues).
* **🌐 Networking:** A clean wrapper around `cpp-httplib` that handles Zlib/Gzip compression automatically.
* **📂 IO:** Memory-mapped file operations and optimized binary stream readers/writers.
* **🛠️ Modern:** Uses `std::span`, `tl::expected`, and C++20 concepts throughout.
**Where to get it:** [https://github.com/I-A-S/IACore](https://github.com/I-A-S/IACore)
Any and all feedback & questions are welcome! (Even the rude ones—I know how r/cpp can be sometimes 😆 ).
# Examples
**1. Async Tasks**
C++
#include <IACore/AsyncOps.hpp>
// Initialize worker threads (hardware_concurrency - 2)
IACore::AsyncOps::InitializeScheduler();
// Schedule a task
auto* mySchedule = new IACore::AsyncOps::Schedule();
IACore::AsyncOps::ScheduleTask([](auto workerID) {
printf("Running on worker %d\n", workerID);
}, 0, mySchedule);
// Wait for completion
IACore::AsyncOps::WaitForScheduleCompletion(mySchedule);
**2. HTTP Request**
C++
#include <IACore/HttpClient.hpp>
IACore::HttpClient client("https://api.example.com");
auto res = client.JsonGet<MyResponseStruct>("/data", {});
if (res) {
std::cout << "Data: " << res->value << "\n";
} else {
std::cerr << "Error: " << res.error() << "\n";
}
**3. IPC (Shared Memory Ring Buffer)**
*Manager:*
C++
#include <IACore/IPC.hpp>
// Spawns a child process and connects via Shared Memory
auto nodeID = manager.SpawnNode("MyChildNodeExe");
manager.WaitTillNodeIsOnline(*nodeID);
// Send data with zero-copy overhead
String msg = "Hello Node";
manager.SendPacket(*nodeID, 100, {(PCUINT8)msg.data(), msg.size()});
*Node:*
C++
#include <IACore/IPC.hpp>
class Node : public IACore::IPC_Node {
public:
void OnSignal(uint8_t signal) override {
// Handle signals
}
void OnPacket(uint16_t packetID, std::span<const uint8_t> payload) override {
// Handle packets
}
};
int main(int argc, char* argv[]) {
// The connection string is passed as the first argument by the Manager
if (argc < 2) return -1;
Node node;
// Connect back to the manager via Shared Memory
if (!node.Connect(argv[1])) return -1;
while(true) {
node.Update();
}
return 0;
}
https://redd.it/1pni3y8
@r_cpp
Hey friends,
Like many of you, I grew tired of "C++ Dependency Hell".. Every time I started a new project (specifically game engines and dev tools), I found myself wasting days setting up the same glue code: finding an HTTP library, setting up a job system, wrestling with platform-specific IPC, and configuring a logger.
I wanted a "bedrock" library—something I could drop into any project and immediately have the essentials working, without linking 50 different `.lib` files manually.
So I built **IACore**. It started as the internal core library for my work at **IASoft**, but I realized it solves a problem almost every C++ dev faces. I’ve cleaned it up, added tests, and I'm open-sourcing it under GPLv3 today.
**What's inside?** It wraps "best-in-class" dependencies into a unified, coherent C++20 API. It manages its own deps via CMake `FetchContent`, so you don't need to install anything manually.
* **⚡ IPC:** High-performance shared-memory ring buffers (wait-free SPSC).
* **🧵 Async:** A work-stealing job scheduler (High/Normal priority queues).
* **🌐 Networking:** A clean wrapper around `cpp-httplib` that handles Zlib/Gzip compression automatically.
* **📂 IO:** Memory-mapped file operations and optimized binary stream readers/writers.
* **🛠️ Modern:** Uses `std::span`, `tl::expected`, and C++20 concepts throughout.
**Where to get it:** [https://github.com/I-A-S/IACore](https://github.com/I-A-S/IACore)
Any and all feedback & questions are welcome! (Even the rude ones—I know how r/cpp can be sometimes 😆 ).
# Examples
**1. Async Tasks**
C++
#include <IACore/AsyncOps.hpp>
// Initialize worker threads (hardware_concurrency - 2)
IACore::AsyncOps::InitializeScheduler();
// Schedule a task
auto* mySchedule = new IACore::AsyncOps::Schedule();
IACore::AsyncOps::ScheduleTask([](auto workerID) {
printf("Running on worker %d\n", workerID);
}, 0, mySchedule);
// Wait for completion
IACore::AsyncOps::WaitForScheduleCompletion(mySchedule);
**2. HTTP Request**
C++
#include <IACore/HttpClient.hpp>
IACore::HttpClient client("https://api.example.com");
auto res = client.JsonGet<MyResponseStruct>("/data", {});
if (res) {
std::cout << "Data: " << res->value << "\n";
} else {
std::cerr << "Error: " << res.error() << "\n";
}
**3. IPC (Shared Memory Ring Buffer)**
*Manager:*
C++
#include <IACore/IPC.hpp>
// Spawns a child process and connects via Shared Memory
auto nodeID = manager.SpawnNode("MyChildNodeExe");
manager.WaitTillNodeIsOnline(*nodeID);
// Send data with zero-copy overhead
String msg = "Hello Node";
manager.SendPacket(*nodeID, 100, {(PCUINT8)msg.data(), msg.size()});
*Node:*
C++
#include <IACore/IPC.hpp>
class Node : public IACore::IPC_Node {
public:
void OnSignal(uint8_t signal) override {
// Handle signals
}
void OnPacket(uint16_t packetID, std::span<const uint8_t> payload) override {
// Handle packets
}
};
int main(int argc, char* argv[]) {
// The connection string is passed as the first argument by the Manager
if (argc < 2) return -1;
Node node;
// Connect back to the manager via Shared Memory
if (!node.Connect(argv[1])) return -1;
while(true) {
node.Update();
}
return 0;
}
https://redd.it/1pni3y8
@r_cpp
GitHub
GitHub - I-A-S/-LEGACY-IACore: [LEGACY] A High-Performance Foundation for Modern C++ 20 Applications
[LEGACY] A High-Performance Foundation for Modern C++ 20 Applications - I-A-S/-LEGACY-IACore
Possible GCC reflection error
Playing with GCC I got a situation like this:
#include <algorithm>
#include <array>
#include <print>
#include <meta>
consteval auto Name(const int integer){
return std::meta::displaystringof(^^integer);
}
consteval auto Name(const std::meta::info meta){
return std::meta::displaystringof(meta);
}
// <source>:21:28: error: call to consteval function 'Name(^^int)' is not a constant expression
// 17 | std::println("{}", Name(^^int));
// | ~~~~^~~~~~~
// But removing const fix it!! (works in Clang P2996)
int main(){
std::println("{}", Name(3));
std::println("{}", Name(^^int));
return 0;
}
I think that this is not the expected behaviour, but is it a known bug to be patched?
https://redd.it/1po9oz2
@r_cpp
Playing with GCC I got a situation like this:
#include <algorithm>
#include <array>
#include <print>
#include <meta>
consteval auto Name(const int integer){
return std::meta::displaystringof(^^integer);
}
consteval auto Name(const std::meta::info meta){
return std::meta::displaystringof(meta);
}
// <source>:21:28: error: call to consteval function 'Name(^^int)' is not a constant expression
// 17 | std::println("{}", Name(^^int));
// | ~~~~^~~~~~~
// But removing const fix it!! (works in Clang P2996)
int main(){
std::println("{}", Name(3));
std::println("{}", Name(^^int));
return 0;
}
I think that this is not the expected behaviour, but is it a known bug to be patched?
https://redd.it/1po9oz2
@r_cpp
Reddit
From the cpp community on Reddit
Explore this post and more from the cpp community
Jubi - Lightweight 2D Physics Engine
Jubi is a passion project I've been creating for around the past month, which is meant to be a lightweight physics engine, targeted for 2D. As of this post, it's on v0.2.1, with world creation, per-body integration, built-in error detection, force-based physics, and other basic needs for a physics engine.
Jubi has been intended for C/C++ projects, with C99 & C++98 as the standards. I've been working on it by myself, since around late-November, early-December. It has started from a basic single-header library to just create worlds/bodies and do raw-collision checks manually, to as of the current version, being able to handle hundreds of bodies with little to no slow down, even without narrow/broadphase implemented yet. Due to Jubi currently using o(n²) to check objects, compilation time can stack fast if used for larger scaled projects, limiting the max bodies at the minute to 1028.
It's main goal is to be extremely easy, and lightweight to use. With tests done, translated as close as I could to 1:1 replicas in Box2D & Chipmunk2D, Jubi has performed the fastest, with the least amount of LOC and boilerplate required for the same tests. We hope, by Jubi-1.0.0, to be near the level of usage/fame as Box2D and/or Chipmunk2D.
Jubi Samples:
#define JUBIIMPLEMENTATION
#include "../Jubi.h"
#include <stdio.h>
int main() {
JubiWorld2D WORLD = JubiCreateWorld2D();
// JBody2DCreateBox(JubiWorld2D *WORLD, Vector2 Position, Vector2 Size, BodyType2D Type, float Mass)
Body2D *Box = JBody2DCreateBox(&WORLD, (Vector2){0, 0}, (Vector2){1, 1}, BODYDYNAMIC, 1.0f);
// ~1 second at 60 FPS
for (int i=0; i < 60; i++) {
JubiStepWorld2D(&WORLD, 0.033f);
printf("Frame: %02d | Position: (%.3f, %.3f) | Velocity: (%.3f, %.3f) | Index: %d\n", i, Box -> Position.x, Box -> Position.y, Box -> Velocity.x, Box -> Velocity.y, Box -> Index);
}
return 0;
}
Jubi runtime compared to other physic engines:
|Physics Engine|Runtime|
|:-|:-|
|Jubi|0.0036ms|
|Box2D|0.0237ms|
|Chipmunk2D|0.0146ms|
Jubi Github: https://github.com/Avery-Personal/Jubi
https://redd.it/1prwf8o
@r_cpp
Jubi is a passion project I've been creating for around the past month, which is meant to be a lightweight physics engine, targeted for 2D. As of this post, it's on v0.2.1, with world creation, per-body integration, built-in error detection, force-based physics, and other basic needs for a physics engine.
Jubi has been intended for C/C++ projects, with C99 & C++98 as the standards. I've been working on it by myself, since around late-November, early-December. It has started from a basic single-header library to just create worlds/bodies and do raw-collision checks manually, to as of the current version, being able to handle hundreds of bodies with little to no slow down, even without narrow/broadphase implemented yet. Due to Jubi currently using o(n²) to check objects, compilation time can stack fast if used for larger scaled projects, limiting the max bodies at the minute to 1028.
It's main goal is to be extremely easy, and lightweight to use. With tests done, translated as close as I could to 1:1 replicas in Box2D & Chipmunk2D, Jubi has performed the fastest, with the least amount of LOC and boilerplate required for the same tests. We hope, by Jubi-1.0.0, to be near the level of usage/fame as Box2D and/or Chipmunk2D.
Jubi Samples:
#define JUBIIMPLEMENTATION
#include "../Jubi.h"
#include <stdio.h>
int main() {
JubiWorld2D WORLD = JubiCreateWorld2D();
// JBody2DCreateBox(JubiWorld2D *WORLD, Vector2 Position, Vector2 Size, BodyType2D Type, float Mass)
Body2D *Box = JBody2DCreateBox(&WORLD, (Vector2){0, 0}, (Vector2){1, 1}, BODYDYNAMIC, 1.0f);
// ~1 second at 60 FPS
for (int i=0; i < 60; i++) {
JubiStepWorld2D(&WORLD, 0.033f);
printf("Frame: %02d | Position: (%.3f, %.3f) | Velocity: (%.3f, %.3f) | Index: %d\n", i, Box -> Position.x, Box -> Position.y, Box -> Velocity.x, Box -> Velocity.y, Box -> Index);
}
return 0;
}
Jubi runtime compared to other physic engines:
|Physics Engine|Runtime|
|:-|:-|
|Jubi|0.0036ms|
|Box2D|0.0237ms|
|Chipmunk2D|0.0146ms|
Jubi Github: https://github.com/Avery-Personal/Jubi
https://redd.it/1prwf8o
@r_cpp
GitHub
GitHub - Avery-Personal/Jubi: Leightweight physics engine written in pure C.
Leightweight physics engine written in pure C. Contribute to Avery-Personal/Jubi development by creating an account on GitHub.
Semantics
Perfect Forwarding
Smart Pointers
constexpr
Initializer Lists
Delegating Constructors
C++14 FEATURES
Generic Lambdas
Return Type Deduction
Binary Literals
Variable Templates
C++17 FEATURES
Structured Bindings
if/switch with initializers
std::optional
std::variant
std::any
Fold Expressions
Inline Variables
C++20 FEATURES
Concepts
Ranges
Coroutines
Modules
Three-way Comparison (<=>)
std::span
MEMORY MANAGEMENT
Stack vs Heap
RAII (Resource Acquisition Is Initialization)
Smart Pointers
- unique_ptr
- shared_ptr
- weak_ptr
Custom Allocators
Memory Pools
EXCEPTION HANDLING
try-catch blocks
throw keyword
Exception Classes
Standard Exceptions
noexcept specifier
Exception Safety Guarantees
FILE I/O
Stream Classes
- ifstream, ofstream, fstream
File Operations
Binary File I/O
String Streams
Formatting
MULTITHREADING
std::thread
Mutexes and Locks
Condition Variables
Atomic Operations
Thread-local Storage
Futures and Promises
async
PREPROCESSOR
Macros
#include
Header Guards
#pragma once
Conditional Compilation
ADVANCED TOPICS
Type Casting
- static_cast
- dynamic_cast
- const_cast
- reinterpret_cast
RTTI (Runtime Type Information)
Operator Overloading
Copy Elision and RVO
Perfect Forwarding
Name Mangling
Linkage
COMPILATION AND BUILD
Compilation Process
Header Files
Source Files
Linking
Build Systems
- Make
- CMake
Compiler Options
Requested a AI to provide a CPP roadmap to know CPP very thoroughly, and it has provided me this roadmap. Do you have additions? Or is this good for modern CPP?
https://redd.it/1pug6hs
@r_cpp
Perfect Forwarding
Smart Pointers
constexpr
Initializer Lists
Delegating Constructors
C++14 FEATURES
Generic Lambdas
Return Type Deduction
Binary Literals
Variable Templates
C++17 FEATURES
Structured Bindings
if/switch with initializers
std::optional
std::variant
std::any
Fold Expressions
Inline Variables
C++20 FEATURES
Concepts
Ranges
Coroutines
Modules
Three-way Comparison (<=>)
std::span
MEMORY MANAGEMENT
Stack vs Heap
RAII (Resource Acquisition Is Initialization)
Smart Pointers
- unique_ptr
- shared_ptr
- weak_ptr
Custom Allocators
Memory Pools
EXCEPTION HANDLING
try-catch blocks
throw keyword
Exception Classes
Standard Exceptions
noexcept specifier
Exception Safety Guarantees
FILE I/O
Stream Classes
- ifstream, ofstream, fstream
File Operations
Binary File I/O
String Streams
Formatting
MULTITHREADING
std::thread
Mutexes and Locks
Condition Variables
Atomic Operations
Thread-local Storage
Futures and Promises
async
PREPROCESSOR
Macros
#include
Header Guards
#pragma once
Conditional Compilation
ADVANCED TOPICS
Type Casting
- static_cast
- dynamic_cast
- const_cast
- reinterpret_cast
RTTI (Runtime Type Information)
Operator Overloading
Copy Elision and RVO
Perfect Forwarding
Name Mangling
Linkage
COMPILATION AND BUILD
Compilation Process
Header Files
Source Files
Linking
Build Systems
- Make
- CMake
Compiler Options
Requested a AI to provide a CPP roadmap to know CPP very thoroughly, and it has provided me this roadmap. Do you have additions? Or is this good for modern CPP?
https://redd.it/1pug6hs
@r_cpp
Reddit
From the cpp community on Reddit
Explore this post and more from the cpp community
Is modules thought to work seamlessly with external dependencies using #import
Let's say I want to convert my project to use modules instead of
What happens with all my external dependencies using
Does this cause conflicts in some way, or does it work seamlessly?
https://redd.it/1q1ekad
@r_cpp
Let's say I want to convert my project to use modules instead of
#includes. So I replace every #include <vector> with import <vector>? What happens with all my external dependencies using
#include <vector>?Does this cause conflicts in some way, or does it work seamlessly?
https://redd.it/1q1ekad
@r_cpp
Reddit
From the cpp community on Reddit
Explore this post and more from the cpp community
MayaFlux 0.1.0: A Digital-Native Substrate for Multimedia Computation
Hello r/cpp folks,
I am very excited to announce the initial release of my new creative multimedia programming framework. Here is a short release text, you can find the full context on the [website](https://mayaflux.org/releases/)
MayaFlux 0.1.0 is a C++20/23 infrastructure built to replace the 1980s-era architectures still underlying modern creative coding tools. Built with 15 years of interdisciplinary practice and DSP engineering, it departs from the "analog metaphors" that have constrained digital creativity since the 1980s. MayaFlux does not simulate oscillators or patch cables; it processes unified numerical streams through lock-free computation graphs.
## The Death of Analog Metaphor
Traditional tools (DAWs, visual patchers) rely on legacy pedagogical metaphors. MayaFlux rejects these in favor of computational logic. In this framework, **audio, visuals, and control data are identical.** Every sample, pixel, and parameter is a double-precision floating-point number. This eliminates the artificial boundaries between domains. A single unit can output audio, trigger GPU compute shaders, and coordinate temporal events in the same processing callback without conversion overhead.
## Technical Core: Lock-Free & Deterministic
Building on C++20, MayaFlux utilizes `atomic_ref` and compare-exchange operations to ensure thread safety without mutexes. You can restructure complex graphs or inject new nodes while audio plays -> no glitches, no dropouts, and no contentions. The state promise ensures every node processes exactly once per cycle, regardless of how many consumers it has, enabling true multi-rate adaptation (Audio, Visual, and Custom rates) within a unified graph.
## Lila: Live C++ via LLVM JIT
One of MayaFlux's most transformative features is the **Lila JIT system**. Utilizing LLVM 21+, Lila allows for full C++20 syntax evaluation (including templates and `constexpr`) in real-time. There is no "application restart" or "compilation wait." You write C++ code, hit evaluate, and hear/see the results within one buffer cycle. Live coding no longer requires switching to a "simpler" interpreted language; you have the full power of the C++ compiler in the hot path.
## Graphics as First-Class Computation
Unlike tools where graphics are a "visualization" afterthought, MayaFlux treats the **Vulkan 1.3** pipeline with the same architectural rigor as audio DSP. The graphics pipeline shares the same lock-free buffer coordination and node-network logic. Whether you are driving vertex displacement via a recursive audio filter or mapping particle turbulence to a high-precision phasor, the data flow is seamless and low-level.
## Temporal Materiality
By utilizing **C++20 Coroutines**, MayaFlux turns Time into a compositional material. Through the `co_await` keyword, developers can suspend logic on sample counts, frame boundaries, or predicates. This eliminates "callback hell" and allows temporal logic to be written exactly how it is imagined: linearly and deterministically.
## Who is it for?
MayaFlux is infrastructure, not an application. It is for:
- **Creative Technologists** hitting the limits of Processing or Max/MSP.
- **Researchers** needing direct buffer access and novel algorithm implementation.
- **Developers** seeking low-level GPU/Audio control without framework-imposed boundaries.
The substrate is ready. Visit **mayaflux.org** to start sculpting data.
## A quick teaser
```cpp
#pragma once
#define MAYASIMPLE
#include "MayaFlux/MayaFlux.hpp"
void settings() {
// Low-latency audio setup
auto& stream = MayaFlux::Config::get_global_stream_info();
stream.sample_rate = 48000;
}
void compose() {
// 1. Create the bell
auto bell = vega.ModalNetwork(
12,
220.0,
ModalNetwork::Spectrum::INHARMONIC)[0]
| Audio;
// 2. Create audio-driven logic
auto source_sine = vega.Sine(0.2, 1.0f); // 0.2 Hz slow oscillator
static double last_input = 0.0;
auto
Hello r/cpp folks,
I am very excited to announce the initial release of my new creative multimedia programming framework. Here is a short release text, you can find the full context on the [website](https://mayaflux.org/releases/)
MayaFlux 0.1.0 is a C++20/23 infrastructure built to replace the 1980s-era architectures still underlying modern creative coding tools. Built with 15 years of interdisciplinary practice and DSP engineering, it departs from the "analog metaphors" that have constrained digital creativity since the 1980s. MayaFlux does not simulate oscillators or patch cables; it processes unified numerical streams through lock-free computation graphs.
## The Death of Analog Metaphor
Traditional tools (DAWs, visual patchers) rely on legacy pedagogical metaphors. MayaFlux rejects these in favor of computational logic. In this framework, **audio, visuals, and control data are identical.** Every sample, pixel, and parameter is a double-precision floating-point number. This eliminates the artificial boundaries between domains. A single unit can output audio, trigger GPU compute shaders, and coordinate temporal events in the same processing callback without conversion overhead.
## Technical Core: Lock-Free & Deterministic
Building on C++20, MayaFlux utilizes `atomic_ref` and compare-exchange operations to ensure thread safety without mutexes. You can restructure complex graphs or inject new nodes while audio plays -> no glitches, no dropouts, and no contentions. The state promise ensures every node processes exactly once per cycle, regardless of how many consumers it has, enabling true multi-rate adaptation (Audio, Visual, and Custom rates) within a unified graph.
## Lila: Live C++ via LLVM JIT
One of MayaFlux's most transformative features is the **Lila JIT system**. Utilizing LLVM 21+, Lila allows for full C++20 syntax evaluation (including templates and `constexpr`) in real-time. There is no "application restart" or "compilation wait." You write C++ code, hit evaluate, and hear/see the results within one buffer cycle. Live coding no longer requires switching to a "simpler" interpreted language; you have the full power of the C++ compiler in the hot path.
## Graphics as First-Class Computation
Unlike tools where graphics are a "visualization" afterthought, MayaFlux treats the **Vulkan 1.3** pipeline with the same architectural rigor as audio DSP. The graphics pipeline shares the same lock-free buffer coordination and node-network logic. Whether you are driving vertex displacement via a recursive audio filter or mapping particle turbulence to a high-precision phasor, the data flow is seamless and low-level.
## Temporal Materiality
By utilizing **C++20 Coroutines**, MayaFlux turns Time into a compositional material. Through the `co_await` keyword, developers can suspend logic on sample counts, frame boundaries, or predicates. This eliminates "callback hell" and allows temporal logic to be written exactly how it is imagined: linearly and deterministically.
## Who is it for?
MayaFlux is infrastructure, not an application. It is for:
- **Creative Technologists** hitting the limits of Processing or Max/MSP.
- **Researchers** needing direct buffer access and novel algorithm implementation.
- **Developers** seeking low-level GPU/Audio control without framework-imposed boundaries.
The substrate is ready. Visit **mayaflux.org** to start sculpting data.
## A quick teaser
```cpp
#pragma once
#define MAYASIMPLE
#include "MayaFlux/MayaFlux.hpp"
void settings() {
// Low-latency audio setup
auto& stream = MayaFlux::Config::get_global_stream_info();
stream.sample_rate = 48000;
}
void compose() {
// 1. Create the bell
auto bell = vega.ModalNetwork(
12,
220.0,
ModalNetwork::Spectrum::INHARMONIC)[0]
| Audio;
// 2. Create audio-driven logic
auto source_sine = vega.Sine(0.2, 1.0f); // 0.2 Hz slow oscillator
static double last_input = 0.0;
auto
mayaflux.org
MayaFlux 0.1.0: Infrastructure for Digital Creativity | MayaFlux
Digital-First Multimedia Computation Framework
MayaFlux 0.1.0: A Digital-Native Substrate for Multimedia Computation
Hello r/cpp folks,
I am very excited to announce the initial release of my new creative multimedia programming framework. Here is a short release text, you can find the full context on the [website](https://mayaflux.org/releases/) or the [git repo](https://github.com/MayaFlux/MayaFlux)
MayaFlux 0.1.0 is a C++20/23 infrastructure built to replace the 1980s-era architectures still underlying modern creative coding tools. Built with 15 years of interdisciplinary practice and DSP engineering, it departs from the "analog metaphors" that have constrained digital creativity since the 1980s. MayaFlux does not simulate oscillators or patch cables; it processes unified numerical streams through lock-free computation graphs.
# The Death of Analog Metaphor
Traditional tools (DAWs, visual patchers) rely on legacy pedagogical metaphors. MayaFlux rejects these in favor of computational logic. In this framework, **audio, visuals, and control data are identical.** Every sample, pixel, and parameter is a double-precision floating-point number. This eliminates the artificial boundaries between domains. A single unit can output audio, trigger GPU compute shaders, and coordinate temporal events in the same processing callback without conversion overhead.
# Technical Core: Lock-Free & Deterministic
Building on C++20, MayaFlux utilizes `atomic_ref` and compare-exchange operations to ensure thread safety without mutexes. You can restructure complex graphs or inject new nodes while audio plays -> no glitches, no dropouts, and no contentions. The state promise ensures every node processes exactly once per cycle, regardless of how many consumers it has, enabling true multi-rate adaptation (Audio, Visual, and Custom rates) within a unified graph.
# Lila: Live C++ via LLVM JIT
One of MayaFlux's most transformative features is the **Lila JIT system**. Utilizing LLVM 21+, Lila allows for full C++20 syntax evaluation (including templates and `constexpr`) in real-time. There is no "application restart" or "compilation wait." You write C++ code, hit evaluate, and hear/see the results within one buffer cycle. Live coding no longer requires switching to a "simpler" interpreted language; you have the full power of the C++ compiler in the hot path.
# Graphics as First-Class Computation
Unlike tools where graphics are a "visualization" afterthought, MayaFlux treats the **Vulkan 1.3** pipeline with the same architectural rigor as audio DSP. The graphics pipeline shares the same lock-free buffer coordination and node-network logic. Whether you are driving vertex displacement via a recursive audio filter or mapping particle turbulence to a high-precision phasor, the data flow is seamless and low-level.
# Temporal Materiality
By utilizing **C++20 Coroutines**, MayaFlux turns Time into a compositional material. Through the `co_await` keyword, developers can suspend logic on sample counts, frame boundaries, or predicates. This eliminates "callback hell" and allows temporal logic to be written exactly how it is imagined: linearly and deterministically.
# Who is it for?
MayaFlux is infrastructure, not an application. It is for:
* **Creative Technologists** hitting the limits of Processing or Max/MSP.
* **Researchers** needing direct buffer access and novel algorithm implementation.
* **Developers** seeking low-level GPU/Audio control without framework-imposed boundaries.
The substrate is ready. Visit **mayaflux.org** to start sculpting data.
# A quick teaser
```cpp
#pragma once
#define MAYASIMPLE
#include "MayaFlux/MayaFlux.hpp"
void settings() {
// Low-latency audio setup
auto& stream = MayaFlux::Config::get_global_stream_info();
stream.sample_rate = 48000;
}
void compose() {
// 1. Create the bell
auto bell = vega.ModalNetwork(
12,
220.0,
ModalNetwork::Spectrum::INHARMONIC)[0]
| Audio;
// 2. Create
Hello r/cpp folks,
I am very excited to announce the initial release of my new creative multimedia programming framework. Here is a short release text, you can find the full context on the [website](https://mayaflux.org/releases/) or the [git repo](https://github.com/MayaFlux/MayaFlux)
MayaFlux 0.1.0 is a C++20/23 infrastructure built to replace the 1980s-era architectures still underlying modern creative coding tools. Built with 15 years of interdisciplinary practice and DSP engineering, it departs from the "analog metaphors" that have constrained digital creativity since the 1980s. MayaFlux does not simulate oscillators or patch cables; it processes unified numerical streams through lock-free computation graphs.
# The Death of Analog Metaphor
Traditional tools (DAWs, visual patchers) rely on legacy pedagogical metaphors. MayaFlux rejects these in favor of computational logic. In this framework, **audio, visuals, and control data are identical.** Every sample, pixel, and parameter is a double-precision floating-point number. This eliminates the artificial boundaries between domains. A single unit can output audio, trigger GPU compute shaders, and coordinate temporal events in the same processing callback without conversion overhead.
# Technical Core: Lock-Free & Deterministic
Building on C++20, MayaFlux utilizes `atomic_ref` and compare-exchange operations to ensure thread safety without mutexes. You can restructure complex graphs or inject new nodes while audio plays -> no glitches, no dropouts, and no contentions. The state promise ensures every node processes exactly once per cycle, regardless of how many consumers it has, enabling true multi-rate adaptation (Audio, Visual, and Custom rates) within a unified graph.
# Lila: Live C++ via LLVM JIT
One of MayaFlux's most transformative features is the **Lila JIT system**. Utilizing LLVM 21+, Lila allows for full C++20 syntax evaluation (including templates and `constexpr`) in real-time. There is no "application restart" or "compilation wait." You write C++ code, hit evaluate, and hear/see the results within one buffer cycle. Live coding no longer requires switching to a "simpler" interpreted language; you have the full power of the C++ compiler in the hot path.
# Graphics as First-Class Computation
Unlike tools where graphics are a "visualization" afterthought, MayaFlux treats the **Vulkan 1.3** pipeline with the same architectural rigor as audio DSP. The graphics pipeline shares the same lock-free buffer coordination and node-network logic. Whether you are driving vertex displacement via a recursive audio filter or mapping particle turbulence to a high-precision phasor, the data flow is seamless and low-level.
# Temporal Materiality
By utilizing **C++20 Coroutines**, MayaFlux turns Time into a compositional material. Through the `co_await` keyword, developers can suspend logic on sample counts, frame boundaries, or predicates. This eliminates "callback hell" and allows temporal logic to be written exactly how it is imagined: linearly and deterministically.
# Who is it for?
MayaFlux is infrastructure, not an application. It is for:
* **Creative Technologists** hitting the limits of Processing or Max/MSP.
* **Researchers** needing direct buffer access and novel algorithm implementation.
* **Developers** seeking low-level GPU/Audio control without framework-imposed boundaries.
The substrate is ready. Visit **mayaflux.org** to start sculpting data.
# A quick teaser
```cpp
#pragma once
#define MAYASIMPLE
#include "MayaFlux/MayaFlux.hpp"
void settings() {
// Low-latency audio setup
auto& stream = MayaFlux::Config::get_global_stream_info();
stream.sample_rate = 48000;
}
void compose() {
// 1. Create the bell
auto bell = vega.ModalNetwork(
12,
220.0,
ModalNetwork::Spectrum::INHARMONIC)[0]
| Audio;
// 2. Create
mayaflux.org
MayaFlux 0.1.0: Infrastructure for Digital Creativity | MayaFlux
Digital-First Multimedia Computation Framework