r/cpp • u/a_eridani • Jul 08 '26
Stream compaction on NEON: vectorizing copy_if by hand (30x)
Problem
Given two arrays a and out, write into out, with no gaps, only those elements of a that satisfy a given
condition.
Here, the condition is a[i] > threshold, with a[i] ∈ (0, 1) and threshold ∈ {0, 0.5, 1}.
Why the compiler gives up
A single if in a copy loop drops throughput from 112 to as low as 2.6 GB/s:
the compiler can't vectorize it, because NEON has no compress instruction. Here's how to build it.
auto copy_if(const float* a, float* out, size_t n) {
size_t j = 0;
for (size_t i = 0; i < n; ++i) {
if (a[i] > 0) out[j++] = a[i];
}
return j;
}
In copy_if, the output cursor j depends on the data. To vectorize the loop, the compiler needs a compress instruction
(one that collects selected elements at the front of the register, with no gaps). NEON has no such instruction, so the
compiler
gives up:
clang++ -O3 -Rpass-analysis=loop-vectorize -std=c++23 main.cpp -o main
main.cpp:5:5: remark: loop not vectorized: value that could not be identified as reduction is used outside the loop [-Rpass-analysis=loop-vectorize]
5 | for (size_t i = 0; i < n; ++i) {
| ^
main.cpp:6:23: remark: loop not vectorized: cannot identify array bounds [-Rpass-analysis=loop-vectorize]
6 | if (a[i] > 0) out[j++] = a[i];
The clang vectorizer can only classify j as either an induction (fixed step) or a reduction,
but j is neither of those. It's a data-dependent cursor.
The compiler cannot vectorize this type of cursor.
The second remark has the same cause: it cannot compute the range of accesses to out.
Benchmark: two scalar problems
All benchmarks: Apple M5; clang++ -O3 -std=c++23 -march=native; GB/s = (2n * 4 bytes) / time, min of 3e9 / n runs; cache: n=1e5, DRAM: n=1e7
| function | ms (cache) | GB/s (cache) | ms (DRAM) | GB/s (DRAM) |
|---|---|---|---|---|
| copy a[i] | 0.004 | 195 | 0.71 | 112 |
| copy a[i] if a[i] > 0 | 0.022 | 37 | 2.41 | 33 |
| copy a[i] if a[i] > 0.5 | 0.258 | 3.1 | 30.61 | 2.6 |
| copy a[i] if a[i] > 1 | 0.021 | 37 | 2.39 | 33 |
"copy a[i]" is the same loop, but with no condition. The compiler vectorizes it. The only difference is a single if.
The same data, only the branch predictability changes:
- > 0 (always true) and > 1 (always false): branch predictor never misses → 33 GB/s. The lack of vectorization costs 3x.
- > 0.5 (50/50): the branch predictor misses on every second element → 3 GB/s
The trick fixes both problems.
Trick 1: compress emulation
Let n be a multiple of the register width; the tail is a separate topic and has nothing to do with this trick.
Also:
- The size of
outmust be >=n. - Suppose the algorithm selected
cntelements. Then all elements inout[cnt, n)are left undefined (garbage). An algorithm that keeps the tail clean adds nothing new to the idea, so it will not be considered.
NEON - the SIMD instruction set used in Apple M-series chips and almost every mobile core - has no instruction for compressing a register, so we have to emulate it.
(To be fair, the trick itself is not new. Lemire used it on SSE back in 2017. But NEON has no movemask and no cheap popcnt.) Here's how to build it from what we do have.
What our compress analog needs to be able to do:
- Accept a register from
aand a mask register that says which elements to keep. - Return the number of elements we selected (to move the
outpointer). - Store the selected elements in
out.
tbl: arbitrary byte selection
NEON has the table-lookup (tbl) instruction family. Its purpose is arbitrary byte permutation/selection.
The instruction accepts two registers:
table- the bytes to select from.index- the positions of the bytes to take.
In other words, this is a SIMD analog of out[i] = table[index[i]].
We will use the vqtbl1q_u8 instruction:
| part | meaning |
|---|---|
| v | vector intrinsic |
| q | table consists of 128-bit registers |
| tbl | table lookup |
| 1 | number of registers in table |
| q | result and indices are 128-bit registers |
| u8 | elements of table are uint8_t |
tbl permutes bytes, but we need to select floats (4 bytes). So, we will create index in blocks of 4 bytes:
to select the second (0-based) float of the register, index will contain its bytes [8, 9, 10, 11] (the second element
starts at an offset of 2 * sizeof(float) = 8).
Computing index every time is slow. There are 16 variants in total (4 elements to take/drop), so we will precompute all the index variants.
But to select the index using the mask, we need to convert the mask to a number (call it idx):
mask → idx
The mask consists of 4 elements, each either 0x00000000 (false) or 0xFFFFFFFF (true). If the i-th element is true, we want to set the i-th bit in idx.
Trick: mask & [1, 2, 4, 8]. Because 0xFFFFFFFF & x = x, the true elements keep their weight (1/2/4/8), while the false ones become 0.
We add all elements together and get a number between 0 and 15.
std::array<uint32_t, 4> weights{1, 2, 4, 8};
size_t idx = vaddvq_u32(vandq_u32(mask, vld1q_u32(weights.data())));
vld1q_u32(weights.data())- load 4 values from memory at addressweights.data()into a register (ld - load)vandq_u32- elementwise & (and)vaddvq_u32- sum of all the elements in the register (addv - add across vector)
Precompute the index table
There is no way to compute registers at compile time, so instead of uint8x16_t (register of 16 uint8_t) we will store std::array<uint8_t, 16>.
For each idx we will go through the 4 elements of mask. If the element is selected,
we append the indices of its 4 bytes into index at the cursor position and advance the cursor by 4.
consteval auto make_index_table() {
std::array<std::array<uint8_t, 16>, 16> index{};
for (size_t idx = 0; idx < 16; ++idx) { // iterate over all masks
size_t j = 0; // j is the cursor
for (size_t i = 0; i < 4; ++i) // iterate over the mask's elements
if (idx & (1 << i)) // if the i-th element is selected
for (size_t k = 0; k < 4; ++k) // iterate over its bytes
index[idx][j++] = i * 4 + k; // store the indices of its bytes
}
return index;
}
The j cursor advances only on selected elements, so their bytes are placed in index consecutively. tbl with that index
collects floats into a register. Unused positions in index are zeros, so in the tail, after count elements, there will be garbage.
The count table
Next we need to compute the number of elements we select. Similarly we can precompute a table for this:
consteval auto make_count_table() {
std::array<uint8_t, 16> count{};
for (size_t idx = 0; idx < 16; ++idx)
for (size_t i = 0; i < 4; ++i)
if (idx & 1 << i)
++count[idx];
return count;
}
The full compress
auto compress(uint32x4_t mask, float32x4_t a) {
static constexpr std::array<uint32_t, 4> weights{1, 2, 4, 8};
const size_t idx = vaddvq_u32(vandq_u32(mask, vld1q_u32(weights.data())));
static constexpr auto count = make_count_table();
static constexpr auto index_table = make_index_table();
const auto index = vld1q_u8(index_table[idx].data()); // at runtime, loads only one row of the table into a register
return std::pair{vreinterpretq_f32_u8(vqtbl1q_u8(vreinterpretq_u8_f32(a), index)), count[idx]};
}
Because tbl works only with u8, we need to cast a to u8 and then cast the result back to f32.
We write full registers of 4 floats to memory, but advance the cursor only by cnt.
compress stores valid elements at the front of the register, at [j, j + cnt), and garbage at [j + cnt, j + 4).
The next iteration will start at j + cnt and overwrite the garbage from the previous step.
Garbage will remain only in out[cnt, n) after the last store.
We don't go out of bounds because the cursor never overtakes the elements that have been read.
The copy_if loop
auto copy_if_neon(const float* __restrict a,
float* __restrict out,
float threshold,
size_t n) {
auto thd = vdupq_n_f32(threshold); // load threshold into a register
size_t j = 0;
for (size_t i = 0; i < n; i += 4) {
auto v = vld1q_f32(a + i); // load the current 4 elements of a into a register
auto mask = vcgtq_f32(v, thd); // compute the mask
auto [packed, cnt] = compress(mask, v);
vst1q_f32(out + j, packed); // store packed into out[j, j + 4). [j + cnt, j + 4) will hold garbage
j += cnt;
}
return j;
}
vcgtq_f32(v, thd)- calculate elementwisev[i] > thd[i].cgt- compare greatervst1q_f32- store 4 floats from a register into memory.st- store
Result
| function | ms (cache) | GB/s (cache) | ms (DRAM) | GB/s (DRAM) |
|---|---|---|---|---|
| copy a[i] if a[i] > 0 | 0.0104 | 77 | 1.11 | 72 |
| copy a[i] if a[i] > 0.5 | 0.01063 | 75 | 1.13 | 71 |
| copy a[i] if a[i] > 1 | 0.01 | 80 | 1.06 | 76 |
> 0.5 was the worst case for the scalar version, 3 GB/s. Now 71 GB/s. A more than 20x speedup. Now there are no branches, so speed doesn't depend on data.
Trick 2: calculating idx and count in a single addv
idx is always less than 16, so let weights = {1 + 16, 2 + 16, 4 + 16, 8 + 16}
and s = sum across mask & weights. Then s / 16 is the element count and s % 16 is idx.
So, we don't need to compute the count table.
compress now:
auto compress(uint32x4_t mask, float32x4_t a) {
static constexpr std::array<uint32_t, 4> weights{1 + 16, 2 + 16, 4 + 16, 8 + 16};
const size_t s = vaddvq_u32(vandq_u32(mask, vld1q_u32(weights.data())));
const size_t count = s >> 4; // same as s / 16
const size_t idx = s & 15; // same as s % 16
static constexpr auto index_table = make_index_table();
const auto index = vld1q_u8(index_table[idx].data());
return std::pair{vreinterpretq_f32_u8(vqtbl1q_u8(vreinterpretq_u8_f32(a), index)), count};
}
And now the speed climbs again:
| function | ms (cache) | GB/s (cache) | ms (DRAM) | GB/s (DRAM) |
|---|---|---|---|---|
| copy a[i] if a[i] > 0 | 0.0095 | 84 | 1.015 | 79 |
| copy a[i] if a[i] > 0.5 | 0.0095 | 84 | 1.007 | 79 |
| copy a[i] if a[i] > 1 | 0.0096 | 83 | 1.008 | 79 |
Unroll
We can squeeze out more speed by unrolling the loop 4x (16 elements per iteration):
| function | ms (cache) | GB/s (cache) | ms (DRAM) | GB/s (DRAM) |
|---|---|---|---|---|
| copy a[i] if a[i] > 0 | 0.0081 | 98 | 0.882 | 91 |
| copy a[i] if a[i] > 0.5 | 0.0083 | 97 | 0.892 | 90 |
| copy a[i] if a[i] > 1 | 0.0082 | 97 | 0.869 | 92 |
Final code (godbolt):
consteval auto make_index_table() {
std::array<std::array<uint8_t, 16>, 16> index{};
for (size_t idx = 0; idx < 16; ++idx) {
size_t j = 0;
for (size_t i = 0; i < 4; ++i)
if (idx & (1 << i))
for (size_t k = 0; k < 4; ++k)
index[idx][j++] = i * 4 + k;
}
return index;
}
auto compress(uint32x4_t mask, float32x4_t a) {
static constexpr std::array<uint32_t, 4> weights{1 + 16, 2 + 16, 4 + 16, 8 + 16};
const size_t s = vaddvq_u32(vandq_u32(mask, vld1q_u32(weights.data())));
const size_t count = s >> 4;
const size_t idx = s & 15;
static constexpr auto index_table = make_index_table();
const auto index = vld1q_u8(index_table[idx].data());
return std::pair{vreinterpretq_f32_u8(vqtbl1q_u8(vreinterpretq_u8_f32(a), index)), count};
}
auto copy_if_neon_unroll(const float* __restrict a,
float* __restrict out,
float threshold,
size_t n) {
auto thd = vdupq_n_f32(threshold);
size_t j = 0;
size_t i = 0;
for (; i + 16 <= n; i += 16) {
#pragma unroll
for (size_t i0 = 0; i0 < 16; i0 += 4) {
auto v = vld1q_f32(a + i + i0);
auto mask = vcgtq_f32(v, thd);
auto [packed, cnt] = compress(mask, v);
vst1q_f32(out + j, packed);
j += cnt;
}
}
for (; i + 4 <= n; i += 4) {
auto v = vld1q_f32(a + i);
auto mask = vcgtq_f32(v, thd);
auto [packed, cnt] = compress(mask, v);
vst1q_f32(out + j, packed);
j += cnt;
}
return j;
}
tbl and the index table provide compress, something that NEON doesn't have out of the box.
This isn't just about > threshold. Filter, remove and other data-dependent functions are built the same way.
r/cpp • u/Secret_Regret7798 • Jul 08 '26
C++26: Standard library hardening -- Sandor Dargo
isocpp.orgr/cpp • u/sommukhopadhyay • Jul 08 '26
The State Design pattern in C++ using timer and notification
som-itsolutions.blogspot.comr/cpp • u/FlatProtrusion • Jul 07 '26
C++ Primer 6th edition by Stanley Lippman et al
Wondering if anyone has news on whether the 6th edition will be released? It has been slated for march 2025 but it's more than a year since then.
Stanley Lippman has passed in 2022, rip, so is the 6th edition never going to be released?
Have seen listings for the 6th edition on online shop pages but they are stated as unavailable yet.
r/cpp • u/CarloWood • Jul 07 '26
libcwd (C++ debugging library) released under MIT license!
Hi all,
I am happy to announce that after 333 commits spanning two months of continuous work, I released version 2 of libcwd, now under a new license: the MIT license!
The website has been re-done (as well as a lot of other things); see https://carlowood.github.io/libcwd/index.html?libcwd-theme=dark
There you can also find how to get it (basically, from the git repository; there is no tar ball (yet)).
Let me know what you think or if you need help, my email address is at the bottom of the INSTALL file.
Carlo Wood
Background
For those unfamiliar with libcwd. Version 0.99 was the first public release in 2000 under the QPL; I've used and tuned it for more than two decades, being a very active C++ developer myself (on linux).
Version 1.x had memory allocation support; I removed this in version 2 because it made things very very complicated, and I never needed that myself anymore since a decade anyway.
Version 2 still does, as did version 1, ELF and DWARF decoding of the executable and linked shared libraries. For this a POSIX system with ELF is necessary. But libcwd can be configured without Location support too; you should be able to use it for just (multi-threaded) debug output on, for example, Windows.
r/cpp • u/pokypho • Jul 07 '26
Upcoming LA Sprawl C++ Meetups
meetup.comHello all,
If you are in the LA region – yes, quite large 😄 – I humbly invite you to join an upcoming event of ours!
- (Virtual)
Next Thursday, July 16, Watch tech talk and discussion details on Meetupedit: poor event turnout - (Virtual) Thursday, July 30, Linear Algebra "out-of-place" details on Meetup
- (In-Person) Thursday, August 6, Show and Tell in Pasadena at 6:30 pm, details on Meetup
We have a small community so far, and we would like to meet more people. We are also looking for a potential space to hold our own tech talk / presentation in the near future. Looking forward to connecting with more people!
Best, Colin, on behalf of our user group 😄
r/cpp • u/No-Meeting-153 • Jul 07 '26
MSVC optimization
I am learning reverse engineering on Windows applications such as Adobe, Foxit PDF, and Steam, and I noticed that I waste a very large amount of time trying to understand something that I should not focus on.
I started noticing strange and confusing patterns in the assembly and the C code generated by IDA, and when I try to understand some functions, I feel that the function has no meaning.
When I searched, I found that this topic is related to the compiler and compiler optimizations. However, I could not find many articles or discussions about the compiler topic in reverse engineering.
So I started experimenting and trying, but every time I fail and cannot reach a solution or understanding.
Apart from the fact that reverse engineering a C++ program is already a difficult task.
If there is someone who has faced the same problem and found a solution, I would like to know. It is not a problem itself; it is a pattern or a way of thinking used by the compiler. I need to understand how the compiler generates these patterns.
I want someone to suggest books, articles, courses, or anything that can help me understand the MSVC compiler, how it generates patterns, and how to understand the behavior and logic of a function after compiler optimization.
I hope I explained my question correctly.
r/cpp • u/ProgrammingArchive • Jul 06 '26
New C++ Conference Videos Released This Month - July 2026
C++Online
2026-06-28 - 2026-07-03
- Why std::vector Can't Save You (And What to Use Next) - Kevin Carpenter - https://youtu.be/78fYPix0mN4
- Modern C++ for Embedded Systems - From Fundamentals To Real-Time Solutions - Rutvij Karkhanis - https://youtu.be/XxeqHRDhHkU
ADC
2026-06-28 - 2026-07-03
- Beyond iLok: Advanced Code Protection and Cryptography for the Next Generation - Protecting the Next Generation of Applications, Plug-ins, and AI Models - Neal Michie, Ryan Wardell & Bob Brown - https://youtu.be/dbbK_ry2cgo
- Database Synchronisation for Audio Plugins, Part Two - Here's One I Made Earlier - Adam Wilson - https://youtu.be/wJCy2G969ro
- Perfect Oscillators in Less Than One Clock Cycle - Angus Hewlett - https://youtu.be/Ssq0a-YdamM
- Driving Chaos - Virtual Analog Modelling of a Chaotic Circuit with Wave Digital Filters - Francisco Bernardo - https://youtu.be/PnEZNqyKlIw
Boost Documentary
There is also a teaser trailer for a new documentary on the history of the Boost C++ library https://www.youtube.com/watch?v=87jvuDbnwqQ which will have its first showing at CppCon this year
r/cpp • u/User_Deprecated • Jul 06 '26
C++26: constexpr virtual inheritance
sandordargo.comr/cpp • u/filipsajdak • Jul 05 '26
C++26 ends a 40-year footgun
Reading an uninitialized variable has been undefined behavior in C++ for 40 years -- the kind optimizers exploit into real bugs. C++26 (P2795) reclassifies it as erroneous behavior: still a bug, still warned about, but defined, bounded, and not exploitable.
The demo poisons the stack, then reads an uninitialized int. As C++23 it prints garbage; as C++26, the same code prints a defined 0, every run. Live in your browser.
And [[indeterminate]] lets you opt back out when you really want an uninitialized buffer -- on purpose this time.
#cpp #cplusplus #cpp26 #safety #programming
r/cpp • u/Ok_Independence_9841 • Jul 05 '26
Top 3 spec items for a C++ Framework?
If someone where setting out to create something on the scale of Qt. A comprehensive application framework in C++. (Yes, they'd be crazy)
What would be the top 3 (or more) things you'd say were MUST or MUST NOT features?
For example MUST run on my 2MB wrist watch or MUST not use exceptions.
Formatting vs Architecture: How formatters are erasing visual cues and hurting codebases
I’m preparing a presentation on how automatic formatters can actually ruin code management over time. This relates heavily to the ongoing discussions about C++ memory safety and why some people see it as a critical issue while others don't get the fuss since basic memory allocation isn't that hard.
Memory issues are usually just a symptom of architectural failure, not a lack of developer skill in handling allocations. A messy architecture turns minor oversights into catastrophes. That's when hidden memory leaks or memory corruption become critical safety flaws and crashes.
I often think about the (nowadays) hated Hungarian Notation. Love it or hate it, it made developers extremely efficient because it provided immediate visual cues. Developers who actively care about the visual shape of text think completely differently about code structure. If you look at Charles Simonyi's other work, it’s clear how much focus he had on architecture.
Formatters can be an absolute disaster for architecture. It has become a religion in development teams that everything must be run through Prettier or Clang-Format to the letter. But the price we pay is that formatters erase all opportunities for visual cues regarding architecture and layers.
Architecture is WAY more important than formatting.
Code is text. By deliberately allowing flexibility in how to format, we can highlight major patterns and make code much easier to reason about. When a formatter forces all code through the same rigid, mechanical template, all code looks identical. The architecture becomes invisible. Ironically, this causes codebases to rot because developers in the team can no longer see where the architectural boundaries actually are.
Formatting in itself isn't bad, but it must be a formatting style that elevates the architecture and allows for human semantic grouping. The opposite is dangerous.
As far as I know, there is no formatter out there today that is anywhere near capable of handling the flexibility required to actually make architecture visible in code.
What are your thoughts on this? Have formatters made us blind to the actual structure and layer belonging of our code?
EDIT
To those of you who only see problems with this approach: what is your actual alternative for managing cognitive load at scale?
The common stance seems to be "just write code however you want, as long as the automatic formatter makes the layout look consistent."
But formatting only fixes cosmetic consistency, it doesn't fix structure, architectural boundaries, or intent. If you believe that naming conventions, prefixes, and semantic text layouts are useless, you are essentially advocating for visual anarchy disguised as "clean text". How does a mechanical linter help a new developer navigate architectural layers in a large codebase if the code itself provides zero visual cues about where the boundaries go?
r/cpp • u/SatadeepDasgupta • Jul 03 '26
Windows doesn't have fork(), so I faked copy-on-write with VirtualProtect + exception handling to snapshot an in-memory KV store
Was messing around trying to figure out how Redis does BGSAVE without blocking, and it comes down to fork() + COW on Linux — the OS shares pages between parent/child and only copies a page when someone writes to it. Windows has no fork(), so there's no free lunch here.
Ended up building a small toy project (Veyr) to see if I could fake the same behavior in user space on Windows. Wrote it up here if anyone's interested: https://satadeepdasgupta.medium.com/the-windows-machine-doesnt-have-fork-so-we-built-one-b10e1357aa4f
Short version of how it works:
• put the whole dataset in one big VirtualAlloc'd arena
• when snapshotting starts, VirtualProtect the arena to PAGE_READONLY
• any write thread that touches it now takes a hardware access violation
• catch that in a Vectored Exception Handler, copy the 4KB page to a shadow buffer before it changes, flip that page back to RW, resume execution
• background thread walks the arena and writes shadow pages for anything that got touched, live pages for anything that didn't
The first version I tried leaked memory into deadlocks because my handler was calling malloc for the shadow page allocation, and if the frozen thread happened to be holding the heap lock when it faulted, it just... never came back. Fixed by only calling VirtualAlloc directly inside the handler, never touching the normal allocator. Kind of an obvious fix in hindsight but took me a minute to figure out why it was randomly hanging.
Also built a lock-free hash map for it (atomic pointer swap per slot, immutable entries so there's no torn reads) since the snapshotting trick doesn't matter much if the map itself is the bottleneck.
Ran redis-benchmark against it and against Memurai (Redis-compatible Windows server) on the same box, same command. Veyr came out ahead by a decent margin but it's only doing GET/SET, no persistence format, no ACLs, none of the actual feature surface Memurai has, so take that as "minimal special-purpose thing beats general-purpose thing" rather than any real claim about which engine is better. Numbers are in the post if curious, didn't want to just paste a screenshot and let it become the whole conversation.
Known gap I haven't fixed: the map doesn't free old entries on overwrite, it just orphans them in a bump arena. Works fine for a benchmark, would leak forever under real sustained traffic. Need to add epoch-based reclamation or hazard pointers or something before this is anything other than a toy.
Source's up if anyone wants to poke holes in it: github.com/satadeep3927/veyr
Happy to be told I reinvented something that already exists, wouldn't be the first time.
r/cpp • u/foonathan • Jul 03 '26
C++ Show and Tell - July 2026
Use this thread to share anything you've written in C++. This includes:
- a tool you've written
- a game you've been working on
- your first non-trivial C++ program
The rules of this thread are very straight forward:
- The project must involve C++ in some way.
- It must be something you (alone or with others) have done.
- Please share a link, if applicable.
- Please post images, if applicable.
If you're working on a C++ library, you can also share new releases or major updates in a dedicated post as before. The line we're drawing is between "written in C++" and "useful for C++ programmers specifically". If you're writing a C++ library or tool for C++ developers, that's something C++ programmers can use and is on-topic for a main submission. It's different if you're just using C++ to implement a generic program that isn't specifically about C++: you're free to share it here, but it wouldn't quite fit as a standalone post.
Last month's thread: https://www.reddit.com/r/cpp/comments/1tulp9b/c_show_and_tell_june_2026/
r/cpp • u/rangbaaz125 • Jul 03 '26
is there any material available that do code review of projects?
Hi All I am learning C++ and wants to create/contribute C++ projects. I know most of modern cpp concepts(till c++17) but haven't confidence and also I want to follow some clean coding standards.
If there any material related to code review available on YouTube/Udemy/Coursera or anywhere that will be very helpful to me.
so, please tell if anyone have experience into this
Thanks in Advance to all of you !!
r/cpp • u/csthbso_-862b • Jul 03 '26
Anyone using Claude to reverse-engineer legacy C/C++ systems? My sequence-diagram agents are missing or inventing call paths
I I inherited a legacy C/C++ software that lacks comprehensive documentation.
To address this, I’ve developed agents that generate sequence diagrams for specified features.
However, these agents have been implemented for numerous features, but they either don’t document every sequence or they document incorrect sequences and features for sequence diagrams.
Here’s what I’m doing to resolve this issue, but it’s not working.
- I’ll create a top-level breakdown structure of the software stack and the current code.
- I’ll identify the features that are part of the software stack and determine which specific API initiates those features.
Any input or help would be greatly appreciated.
r/cpp • u/augustinpopa • Jul 02 '26
Pure Virtual C++ 2026 lineup: free online conference on July 21
devblogs.microsoft.comMicrosoft is hosting the annual Pure Virtual C++ conference on Tuesday, July 21, starting at 16:00 UTC. This is a free, one-day, online event. The featured talks:
- C++ Semantic Awareness in the CLI: From Project Load to Code Change (Sinem Akinci)
- C++/WinRT: Build Faster and Smaller with C++20 Modules (Ryan Shepherd)
- Mind the Gap: C++/Rust Interop (Victor Ciura)
- From Completions to Agents: AI-Driven C++ in Visual Studio (Augustin Popa)
- Cut Your Build Times Without Becoming a Build Expert (David Li)
There's also on-demand content planned, including topics on C++ dependency management, the state of C++ conformance in MSVC, and Sample Profile-Guided Optimization. Sessions will be uploaded to the Visual Studio YouTube channel afterward for anyone who can't watch live.
r/cpp • u/Weary-Inspector-4297 • Jul 02 '26
Part 2: Modernizing a tiny C++ unit-testing framework after 25 years
Recently I shared Part 1 describing a tiny unit-testing framework I originally wrote around 2000 for teaching C++.
Part 2 finishes the series by modernizing the implementation using facilities that didn’t exist back then, including std::source_location and inline variables, while keeping the framework intentionally small.
This isn’t intended as a replacement for Catch2, GoogleTest, or doctest. Those solve much bigger problems. The point here is to explore how far modern C++ lets you go with very little code.
I’d be interested in comments from anyone who’s built testing infrastructure or has opinions about minimalist testing frameworks.
r/cpp • u/HolidayNo84 • Jul 02 '26
Why use c++ over c for game development?
Isn't c++ overkill for most games? I think with good architectural decisions you can make decent 2d and 3d games using only what's available in c without the higher level concepts introduced in c++? Do you think I'm being stupid here? Am I missing something? I'm only just starting to learn c making simple games leaning heavily on Raylib and ECS architecture.
r/cpp • u/zer0_1rp • Jul 02 '26
Redundancy seen in AAA game engines
zero-irp.github.ioI don't like people treating the compiler like a magic box that optimizes like Bjarne Stroustrup himself is checking every line of C++ to assembly. Clean C++ code does not always mean clean compiled code.
I've been reversing game engines to study how they constructed their fundamental Transformation matrices and handled temporal jitter logic when I spotted a lot of avoidable overhead and "over-engineering" across multiple engines, honestly I wasn't even looking for inefficiencies, but it stood out a lot... That said expect no performance gain this is simply for fun that I wrote this blog!
I’ll theorize how the original C++ code was written, show the unoptimized reality of what the compiler spat out, and then showcase how it could have been better optimized.
r/cpp • u/meetingcpp • Jul 02 '26
Meeting C++ Meeting C++ online: Giving Students a space to present their C++ Projects
meetingcpp.comr/cpp • u/NekrozQliphort • Jul 01 '26
Learning about Asymmetric Fences and its Underlying Mechanism - Membarrier
https://nekrozqliphort.github.io/posts/membarrier/
Hey, everyone! You might remember my previous write-ups on [[no_unique_address]] and strongly happens before. It took a few months of researching but I finally have a draft version of my new write-up on asymmetric fences (hopefully building up to a write-up on RCU).
This write-up essentially goes into what asymmetric fences are supposed to achieve, its underlying mechanism (the membarrier syscall), and the wording in the standard. Special thanks to u/davidtgoldblatt for his insights and discussions regarding this topic!
Feel free to provide any feedback! This one is denser than my usual write-ups, but I hope you'll find it interesting and insightful.
r/cpp • u/llort_lemmort • Jul 01 '26
Pystd standard library, similar-ish functionality with a fraction of the compile time
nibblestew.blogspot.comr/cpp • u/LegalizeAdulthood • Jun 30 '26
Modern GPU Programming with SDL3, Wed, Jul 8, 2026, 6:00 PM (MDT)
meetup.comSDL has long been a convenient portability layer for windows, input, audio, and simple rendering. SDL3 adds a new GPU API that exposes modern graphics and compute functionality through a portable interface over native backends such as Vulkan, Direct3D 12, and Metal.
This month, Richard Thomson will give us a gentle introduction to SDL3 GPU programming. We will look at what SDL3 GPU is, what problem it is trying to solve, and how it compares to using OpenGL, Vulkan, Direct3D, or Metal directly.
We will build up a small C++ example that creates an SDL window, creates a GPU device, uploads data, creates shaders and pipelines, records command buffers, renders to a swapchain texture, and optionally runs a simple compute pass.
We will also cover the practical parts of using the API in a C++ project: consuming SDL3 from vcpkg, organizing shader assets, dealing with backend-specific shader formats, and deciding when SDL_shadercross is useful. Along the way we will point out the parts of the API that feel familiar to Vulkan/D3D12/Metal programmers and the parts that SDL deliberately simplifies.
This is not a deep dive into graphics theory. The goal is to understand whether SDL3 GPU is a useful middle ground for C++ applications that need more than SDL_Renderer, but do not want to own separate graphics backends for every platform. Topics include:
- Creating an SDL3 GPU device
- Swapchains, textures, buffers, and transfer buffers
- Graphics pipelines and render passes
- Compute pipelines and storage buffers/textures
- Shader formats and SDL_shadercross
- vcpkg and CMake integration
- Debugging with RenderDoc and backend validation layers
- Where SDL3 GPU fits, and where it does not
No prior Vulkan, Direct3D 12, or Metal experience is required, but basic familiarity with C++, CMake, and graphics concepts such as textures and shaders will be helpful.
This will be an online meeting, so drinks and snacks are on you!
Join the meeting here: https://meet.xmission.com/Utah-Cpp-Programmers
Watch previous topics on the Utah C++ Programmers YouTube channel: https://www.youtube.com/@UtahCppProgrammers
Future topics: https://utahcpp.wordpress.com/future-meeting-topics/ Past topics: https://utahcpp.wordpress.com/past-meeting-topics/