-
Stay up-to-date with everything C++! Content directly fetched from the subreddit just for you. Join our group for discussions : @programminginc Powered by : @r_channels
How I Set Up VS Code for Competitive Programming / DSA in C++ (Windows)
After trying many setups, I finally created a clean VS Code environment for C++ + Competitive Programming.
Now I have:
* Separate folders for source code and `.exe`
* One-click compile & run
* `input.txt` and `output.txt`
* GitHub integration
* Clean project structure
This setup feels much better than online IDEs for serious DSA practice.
# 1. Install VS Code
Download:
[https://code.visualstudio.com/](https://code.visualstudio.com/)
Install normally.
# 2. Install MinGW (g++ compiler)
Download MinGW:
[https://sourceforge.net/projects/mingw/](https://sourceforge.net/projects/mingw/)
While installing select:
* `mingw32-gcc-g++`
After installation, your compiler path usually becomes:
C:\MinGW\bin
# 3. Add MinGW to PATH
Search:
Environment Variables
Open:
Edit the system environment variables
Then:
Environment Variables
→ Path
→ Edit
→ New
Add:
C:\MinGW\bin
Click OK everywhere.
Restart VS Code completely.
# 4. Verify Compiler
Open terminal in VS Code:
Ctrl + `
Run:
g++ --version
If installed correctly, it will show GCC version.
# 5. Install VS Code Extensions
Install these:
* C/C++
* Code Runner (optional)
# 6. Create Folder Structure
I use this structure:
DSA/
│
├── code/
│
├── exe/
│
├── input.txt
├── output.txt
│
├── .vscode/
│ └── tasks.json
│
├── .gitignore
└── README.md
This keeps everything clean.
# 7. Setup Input / Output Redirection
Inside every CPP file:
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
Now:
* input comes from `input.txt`
* output goes to `output.txt`
No need to type input repeatedly in terminal.
# 8. Create tasks.json for One-Key Run
Create:
.vscode/tasks.json
Paste this:
{
"version": "2.0.0",
"tasks": [
{
"label": "Run C++",
"type": "shell",
"command": "cmd",
"args": [
"/c",
"g++ \"${file}\" -o exe\\${fileBasenameNoExtension}.exe && exe\\${fileBasenameNoExtension}.exe"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "shared"
},
"problemMatcher": []
}
]
}
Now press:
Ctrl + Shift + B
and current file automatically:
* compiles
* generates `.exe`
* runs
# 9. Recommended VS Code Layout
I split the screen into 3 sections:
Left:
code.cpp
Top-right:
input.txt
Bottom-right:
output.txt
Use:
Ctrl + \
to split editor.
This setup is AMAZING for CP practice.
# 10. GitHub Setup
Initialize repo:
git init
git add .
git commit -m "Initial commit"
Connect GitHub:
git remote add origin YOUR_REPO_URL
git branch -M main
git push -u origin main
Future workflow:
git add .
git commit -m "Solved new problem"
git push
# 11. Important .gitignore
Create:
.gitignore
Add:
*.exe
output.txt
Don’t push generated binaries.
# Final Thoughts
This setup improved my workflow A LOT.
Benefits:
* cleaner practice
* reusable workflow
* faster debugging
* organized DSA repo
* GitHub tracking
* professional structure
If anyone wants, I can also share:
* VS Code settings
* debugging setup
* contest workflow
https://redd.it/1thf84i
@r_cpp
Built full disassembler & decompiler for Reverse Engineering | Free and open source.
https://github.com/Sidenai/hyperion-disassembler
https://redd.it/1thbmi8
@r_cpp
CppCon 2026 Hudson River Trading Scholarship
Hi all, unfortunately got rejected for the above, but the denial email mentions a "priority waitlist." Supposedly, if someone who got it ends up not going I might have another chance, but I have a feeling that's cope and they send that out to everyone they deny.
Posting to ask if any other student who applied and was denied to the scholarship got a similar rejection or if they got something different.
If you got accepted, congratulations, and make the best of it!
https://redd.it/1tgzc54
@r_cpp
A two phase to-string API? First compute the total size of the single allocation then populate the bytes?
I'm trying to see if there is any prior art in the to-string space that accomplishes a two phase approach. In theory, you could design an API that first asks the data "How many bytes would it take to make you into a string?". From there it could allocate memory with that capacity. Then it could provide that allocation to the same data to populate the bytes.
I want it to be very light weight and easy to add to a type. The `AbslHashValue(...)` API really nails the ergonomics of an extension point in C++, imo. But when it comes to to-string, it gets pretty hairy pretty fast.
`AbslHashValue(...)` benefits from the fact that the resulting hash has a fixed bit width. You just combine/combine_contiguous recursively and you're done.
Some hypothetical `MyToString(...)` would need to likely be split into two functions. `MyToStringSize(...)` and `MyToStringValue(...)` which already makes it more obnoxious to add support for in your type.
But it gets worse. What if inclusion of the type names is important? I can imagine wanting a lever at the top level that says do or do not include them. So for the case where you do include them, how do you succinctly compute the length of namespace + scope-resolution-operator + type name.
And what about templates? Do you also include the angle brackets? Do you recursively include type names between them? And what about potential line noise like allocator types? I can see wanting to include them and not wanting to include them.
Further, what about hashtables? If you store the keys and values in separate ranges for a more data oriented design, how do you model the fact that each K-V pair goes together? You don't want to copy them because that might be expensive. So do you supply a proxy object where it has two pointers? Now that means you have to build an entire TYPE inside your type just to support to-string. Not very ergonomic.
Anyway, wanted to discuss this to see if anyone has ideas in this space. It seems to me that to-string as an operation should be unambiguously single allocation. But unless I'm mistaken, `absl::StrCat(...)` and other such APIs only "limit" the number of allocations and cannot put the upper bound at exactly 1.
https://redd.it/1tgqkd2
@r_cpp
[https://youtu.be/8jA6Dg5iqfw](https://youtu.be/8jA6Dg5iqfw)
* Converting Source Separation Models to ONNX for Real Time Usage in DJ Software - Anmol Mishra - ADC 2025 - [https://youtu.be/CNs9EgMBocI](https://youtu.be/CNs9EgMBocI)
2026-04-27 - 2026-05-03
* From Paper to Plugin - A Guided Tour of Digital Filters - Ross Chisholm, Joel Ross & James Hallowell - ADC 2025 - [https://youtu.be/QlyWAfRUF30](https://youtu.be/QlyWAfRUF30)
* From Idea to Online Sale - The Full Journey of Building an Audio Plugin - Joaquin Saavedra - ADCx Gather 2025 - [https://youtu.be/mJoAArwAmkc](https://youtu.be/mJoAArwAmkc)
* Finding OSCar: Electronic and Software Secrets of a Classic Vintage Synth - Ben Supper - ADC 2025 - [https://youtu.be/NbIZEur3h7Q](https://youtu.be/NbIZEur3h7Q)
https://redd.it/1tgp71x
@r_cpp
Feeling good
I was deep diving into c++
i started from smart pointers
learning about them indepth...deviated to learning about move operator and its implemention inside classes
and learned about NRVO (Named Return Value Optimization) while understanding move operator in depth
This journey really enlightened me; all those small doubts we get clarifed along the path it really makes me happy
finally feeling happy 😄
Never stop asking why +> you will always learn some thing new
https://redd.it/1tgntbk
@r_cpp
CppCast: GPU Programming and HLSL with Chris Bieneman
https://cppcast.com/gpu_programming_and_hlsl_with_chris_bieneman/
https://redd.it/1tgi9s9
@r_cpp
I built a simple, lightweight pixel art editor in C++ (Source code in comments)
Hey guys,
I wanted a lightweight desktop tool to draw pixel art and animations without any bloat, so I spent some free time building one in C++ using SDL2 and ImGui.
It has basic layer support with different blend modes, an animation timeline with onion skinning, custom palette support, and basic shape tools. I also set up the main loop to yield when you aren't drawing, so it uses practically zero CPU when idle.
The source code and portable Windows build are completely free and open-source. I will drop the GitHub link in the comments below!
I'd love to hear your thoughts and suggestions on what features or tools I should add next.
Repo links: https://github.com/YGCODES1/SpriteAnim
Thanks for Support
https://redd.it/1tgffsj
@r_cpp
Auto Non-Static Data Member Initializers are holding back lambdas in RAII (+ coroutine workaround)
TLDR: Auto non-static data member variables allow objects to store lambdas, thereby improving readability and reducing the need for type erasure.
Type deduction and `auto` variables are one of the defining features of modern C++, but unfortunately they are not available to class data members:
struct {
// error: non-static data member declared with placeholder 'auto'
auto x = 1;
// error: invalid use of template-name 'std::vector' without an argument list
std::vector y { 1, 2, 3 };
}
This blog post (from 2018!) by Corentin Jabot does a good job outlining this problem so I'll point to it first: [The case for Auto Non-Static Data Member Initializers](https://cor3ntin.github.io/posts/auto_nsdmi/). However, I would like to expand specifically on lambdas as they are mostly glossed over.
Lambdas can only be stored in `auto` variables because each lambda is given a unique type, even if two lambdas are identical in their definition. As pointed out in the blog post, even `decltype([]{}) foo = []{};` is not permitted.
Because of this it is not possible to store a lambda inside an object, even if the storage requirements can otherwise easily be determined.
**Real world example**
An embedded project I am working on makes heavy use of RAII: so much so that most of our subsystems have little to no functional code, just classes composed of lower level building blocks as data members (representing e.g. GPIOs, UARTs) and some minimal routing between them.
This routing usually takes the form of RAII event callback objects that store the callback function, register themselves in an intrusive list to receive the events, and unregister themselves on destruction. This ensures that we can freely shut down subsystems without worrying about lifetime issues - destruction is always in reverse order and easy to understand at a glance.
struct gpio_uart_forwarder {
peripheral::gpio gpio_in {};
peripheral::gpio gpio_out {};
peripheral::uart uart {};
evt::callback<bool> gpio_to_uart { gpio_in.on_change, [&](bool high) {
uart.write(high ? '1' : '0');
} };
evt::callback<char> uart_to_gpio { uart.on_char, [&](char c) {
if (c == '1') gpio_out.set(1);
else if (c == '0') gpio_out.set(0);
} };
}
The only way this is currently possible is using type erasure, i.e. `std::[move_only_]function`.
In an ideal world, we would instead have the callback templated on the function type:
template<typename Ev, std::invocable<const Ev &> Fn>
class callback {
Fn f;
...
}
And our class would look like:
struct gpio_uart_forwarder {
...
auto gpio_to_uart = evt::callback { gpio_in.on_change, [&](bool high) { ... } };
// OR
evlp::callback uart_to_gpio { uart.on_char, [&](char c) { ... } };
}
While an `std::function` might not seem like a huge price to pay, across an entire program it builds up to hundreds of unnecessary heap allocations, thousands of bytes wasted and extra indirections - all for type erasure that we don't actually need! We know all the types involved, and we own the storage ourselves.
**Proposal to fix**
The last time a formal proposal was made to fix this was way back in 2008 by Bill Seymour: [N2713 - Allow `auto` for non-static data members](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2713.html).
I understand there are complications in determining the size and layout of objects with auto members, but 18 years later this seems like pretty low hanging fruit compared to what has recently been achieved with reflection!
Edge cases such as recursive definitions and references to `this` or `sizeof` should simply be banned rather than resulting in the feature being disabled entirely.
**Coroutine workaround**
In my quest for a solution I have discovered that coroutines can be abused to get the best of both worlds.
If
C++ Liquid Glass [ Show and Tell ]
https://github.com/Aarav90-cpu/Cpp-Liquid-Glass
https://redd.it/1tfozks
@r_cpp
std::is_heap could be faster - Arthur O'Dwyer
https://quuxplusone.github.io/blog/2026/05/11/is-heap/
https://redd.it/1tf9sbi
@r_cpp
GitHub rigx, toml->nix build system for c/cpp/go/zig/etc. Looking for fedback
https://github.com/unofficialtools/rigx
https://redd.it/1tecym6
@r_cpp
- YouTube The Story of C++ documentary trailer in live on CultRepo
https://youtu.be/NXwTRzywDSk?si=8sZEwFUdZW2-Kir4
https://redd.it/1tdolzg
@r_cpp
C++26 Shipped a SIMD Library Nobody Asked For
https://lucisqr.substack.com/p/c26-shipped-a-simd-library-nobody
https://redd.it/1tdhnxj
@r_cpp
C++: The Documentary TRAILER│COMING JUNE 4th
https://youtu.be/NXwTRzywDSk?is=zkrD4Ae_mnrbvSFq
https://redd.it/1td81ye
@r_cpp
Unigine - An engine fundamental to C++
https://youtu.be/WMz5XrBDgag
https://redd.it/1thfdpq
@r_cpp
Neoclassical C++: segmented iterators revisited (1)
Hi,
I written a blog post revisiting Matt Austern's great Segmented Iterators and Hierarchical Algorithms paper (2000) and benchmarking an experimental implementation I've been playing with in Boost.Container.
Quick idea: std::deque and friends are internally segmented (blocks of contiguous memory), but STL-like iterators hide that, so every ++it has to check for a block boundary. Austern's proposal splits the iterator into a segment_iterator (walks blocks) + local_iterator (inside one block), so algorithms can run a tight loop per block and only do bookkeeping at the boundaries.
I benchmarked several "simple" STL algorithms on a Boost deque, and the speedup is way bigger than Austern's original estimation when modern auto-vectorizers enter them game.
Article link: https://boostedcpp.net/2026/05/18/neoclassical-c-segmented-iterators-revisited-1/
Happy to receive feedback!
https://redd.it/1th1e21
@r_cpp
Bjarne Stroustrup interviewed by Ryan Peterman
https://www.youtube.com/watch?v=U46fJ2bJ-co
https://redd.it/1tgtllt
@r_cpp
Simulating Infinity in Conway's Game of Life with Modern C++
https://ryanjk5.github.io/posts/GOLDE/
https://redd.it/1tgo7k8
@r_cpp
New C++ Conference Videos Released This Month - May 2026 (Updated To Include Videos Released 2026-05-11 - 2026-05-17)
**CppCon**
2026-05-11 - 2026-05-17
* Lightning Talk: Reducing Binary Bloat With Thin Archives - Florent Castelli - CppCon 2025 - [https://youtu.be/xs1y0Dl4zZs](https://youtu.be/xs1y0Dl4zZs)
* Lightning Talk: Poor Man’s Autocomplete for Template Arguments - Max Sagebaum - CppCon 2025 - [https://youtu.be/DkLSHgxf-Q8](https://youtu.be/DkLSHgxf-Q8)
* Lightning Talk: The Classic Missed-Signal! - Gopal Rander - CppCon 2025 - [https://youtu.be/8Ign1X3qkgk](https://youtu.be/8Ign1X3qkgk)
* Lightning Talk: Proof Searching in DepC - Raffaele Rossi - CppCon 2025 - [https://youtu.be/sB-mQRsXv1M](https://youtu.be/sB-mQRsXv1M)
* Lightning Talk: Bool - Implicitly Dangerous - Jeff Garland - CppCon 2025 - [https://youtu.be/PcerWZRm\_eA](https://youtu.be/PcerWZRm_eA)
2026-05-04 - 2026-05-10
* Lightning Talk: The Type Safe Builder Pattern for C++ - John Stracke - [https://youtu.be/u5EG21amqlM](https://youtu.be/u5EG21amqlM)
* Lightning Talk: Back When ChatGpt Was Young And Stupid - Andrei Zissu - [https://youtu.be/q6-RSkQRmw0](https://youtu.be/q6-RSkQRmw0)
* Lightning Talk: Learning C++ Through Writing Coding Questions - Christopher DeGuzman - [https://youtu.be/FX63YwZ8OIs](https://youtu.be/FX63YwZ8OIs)
* Lightning Talk: Promote Modern C++ Usage With Coding Questions Part 2 - Zhenchao Lin - [https://youtu.be/uTCxKPaPsdM](https://youtu.be/uTCxKPaPsdM)
* Lightning Talk: std::move & Spirited Away: When Nameless Objects Walk the Spirited World - Siyu (Alice) Peng - [https://youtu.be/ffEOHVm7b4Y](https://youtu.be/ffEOHVm7b4Y)
2026-04-27 - 2026-05-03
* Lightning Talk: A Pragmatic Approach to C++: Designing, Organizing and Writing Maintainable Code - Oleg Rabaev - [https://youtu.be/re4Oy1IVj-s](https://youtu.be/re4Oy1IVj-s)
* Lightning Talk: Causal Inference for Code Writing AI - Matt K Robinson - [https://youtu.be/craQCfj73CI](https://youtu.be/craQCfj73CI)
* Lightning Talk: Cut the boilerplate with C++23 deducing\_this - Sarthak Sehgal - [https://youtu.be/o3vjUo2qXNg](https://youtu.be/o3vjUo2qXNg)
* Lightning Talk: The Lifecycle of This CMake Lightning Talk - Yannic Staudt - [https://youtu.be/3DqRIxXVfiI](https://youtu.be/3DqRIxXVfiI)
* Lightning Talk: Catching Performance Issues at Compile Time - Keith Stockdale - [https://youtu.be/YK8Kwj9okRk](https://youtu.be/YK8Kwj9okRk)
**C++Online**
2026-05-11 - 2026-05-17
* RPC with RAII and C++ Coroutines - Edward Boggis-Rolfe - C++Online 2026 - [https://youtu.be/JjEcSONwhHE](https://youtu.be/JjEcSONwhHE)
* C++ for High Performance Web Application Backends - Uzochukwu Ochogu - C++Online 2026 - [https://youtu.be/ulen8XhMeRA](https://youtu.be/ulen8XhMeRA)
2026-05-04 - 2026-05-10
* MayaFlux: Real-Time Audio-Graphics Coordination in C++20 (Coroutines, Lock-Free) - Ranjith Hegde - [https://youtu.be/\_qZvFNCYQ74](https://youtu.be/_qZvFNCYQ74)
* C++ for High Performance Web Application Backends - Uzochukwu Ochogu - [https://youtu.be/ulen8XhMeRA](https://youtu.be/ulen8XhMeRA)
2026-04-27 - 2026-05-03
* From 5000ns to 200ns - 5 Modern C++ Techniques Live Demo - Larry Ge - [https://youtu.be/9HqyiTWLENY](https://youtu.be/9HqyiTWLENY)
**Audio Developer Conference**
2026-05-11 - 2026-05-17
* Sneak Peek at ARA Audio Random Access 3.0 - Embracing Audio Synthesis - Stefan Gretscher - ADC 2025 - [https://youtu.be/a3T1BBIOBH4](https://youtu.be/a3T1BBIOBH4)
* Raga as Data - Symbolic Music Representations for Analysis, Visualization, and Audio Tools - Soham Korade - ADCx India 2026 - [https://youtu.be/LPiOnLAbZDA](https://youtu.be/LPiOnLAbZDA)
* Cross-Platform Music Software with Rust - Ian Hobson - ADC 2025 - [https://youtu.be/YLPglu2enaE](https://youtu.be/YLPglu2enaE)
2026-05-04 - 2026-05-10
* Continuous QA Testing for Plugins Using AI and Python - Ryan Wardell - [https://youtu.be/w1hLmNPxOV4](https://youtu.be/w1hLmNPxOV4)
* Using Kotlin/Compose Multiplatform to Revive a Historic Multiplayer Online Drum Machine - How To Write An Audio App That Runs Almost Everywhere - Phil Burk -
Faster than std::sort and pdqsort
https://easylang.online/blog/blqsort
https://redd.it/1tgltt5
@r_cpp
Fireside Chat with Bjarne Stroustrup at CTO Summit 2025 Hamburg
https://www.youtube.com/watch?v=hqUItF7m3tk
https://redd.it/1tgh3v5
@r_cpp
you don't need external access to the data members and just want to benefit from RAII, you can convert the class to a coroutine that suspends itself right before ending:
class scope {
public:
struct promise_type {
scope get_return_object() noexcept {
return scope { std::coroutine_handle<promise_type>::from_promise(*this) };
}
std::suspend_never initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() noexcept {}
void unhandled_exception() { std::terminate(); }
};
...
~scope() {
if (!this->handle) return;
this->handle.destroy();
this->handle = {};
}
private:
explicit scope(std::coroutine_handle<promise_type> h) noexcept : handle(h) {}
std::coroutine_handle<promise_type> handle {};
};
scope gpio_uart_forwarder() {
auto gpio_in = peripheral::gpio {};
auto gpio_out = peripheral::gpio {};
auto uart = peripheral::uart {};
auto gpio_to_uart = evt::callback { gpio_in.on_change, [&](bool high) {
uart.write(high ? '1' : '0');
} };
auto uart_to_gpio = evt::callback { uart.on_char, [&](char c) {
if (c == '1') gpio_out.set(1);
else if (c == '0') gpio_out.set(0);
} };
// All local variables remain alive until coroutine is destroyed
co_await std::suspend_always();
// Can't rely on final_suspend because stack is already destroyed by then
// But we need a co_ statement anyway to turn it into a coroutine
}
scope my_gpio_uart_forwarder = gpio_uart_forwarder();
Far from perfect, but it reduces us to a single heap allocation plus the minimal overhead of launching the coroutine, no matter how many callbacks we define.
Maybe the best part is it can be used *within* an existing class too, preserving standard object RAII:
struct gpio_uart_forwarder {
peripheral::gpio gpio_in {};
peripheral::gpio gpio_out {};
peripheral::uart uart {};
scope callbacks = [&] -> scope {
auto gpio_to_uart = evt::callback { gpio_in.on_change, [&](bool high) {
uart.write(high ? '1' : '0');
} };
auto uart_to_gpio = evt::callback { uart.on_char, [&](char c) {
if (c == '1') gpio_out.set(1);
else if (c == '0') gpio_out.set(0);
} };
co_await std::suspend_always();
}();
}
https://redd.it/1tg6mzu
@r_cpp
Auto Non-Static Data Member Initializers are holding back lambdas in RAII (+ coroutine workaround)
TLDR: Auto non-static data member variables allow objects to store lambdas, thereby improving readability and reducing the need for type erasure.
Type deduction and auto variables are one of the defining features of modern C++, but unfortunately they are not available to class data members:
struct {
// error: non-static data member declared with placeholder 'auto'
auto x = 1;
// error: invalid use of template-name 'std::vector' without an argument list
std::vector y { 1, 2, 3 };
}
This blog post (from 2018!) by Corentin Jabot does a good job outlining this problem so I'll point to it first: The case for Auto Non-Static Data Member Initializers. However, I would like to expand specifically on lambdas as they are mostly glossed over.
Lambdas can only be stored in auto variables because each lambda is given a unique type, even if two lambdas are identical in their definition. As pointed out in the blog post, even decltype([]{}) foo = []{}; is not permitted.
Because of this it is not possible to store a lambda inside an object, even if the storage requirements can otherwise easily be determined.
Real world example
An embedded project I am working on makes heavy use of RAII: so much so that most of our subsystems have little to no functional code, just classes composed of lower level building blocks as data members (representing e.g. GPIOs, UARTs) and some minimal routing between them.
This routing usually takes the form of RAII event callback objects that store the callback function, register themselves in an intrusive list to receive the events, and unregister themselves on destruction. This ensures that we can freely shut down subsystems without worrying about lifetime issues - destruction is always in reverse order and easy to understand at a glance.
struct gpiouartforwarder {
peripheral::gpio gpioin {};
peripheral::gpio gpioout {};
peripheral::uart uart {};
evt::callback<bool> gpiotouart { gpioin.onchange, & {
uart.write(high ? '1' : '0');
} };
evt::callback<char> uarttogpio { uart.onchar, [&](char c) {
if (c == '1') gpioout.set(1);
else if (c == '0') gpioout.set(0);
} };
}
The only way this is currently possible is using type erasure, i.e. `std::[moveonly]function`.
In an ideal world, we would instead have the callback templated on the function type:
template<typename Ev, std::invocable<const Ev &> Fn>
class callback {
Fn f;
...
}
And our class would look like:
struct gpiouartforwarder {
...
auto gpiotouart = evt::callback { gpioin.onchange, [&](bool high) { ... } };
// OR
evlp::callback uarttogpio { uart.onchar, & { ... } };
}
While an std::function might not seem like a huge price to pay, across an entire program it builds up to hundreds of unnecessary heap allocations, thousands of bytes wasted and extra indirections - all for type erasure that we don't actually need! We know all the types involved, and we own the storage ourselves.
Proposal to fix
The last time a formal proposal was made to fix this was way back in 2008 by Bill Seymour: N2713 - Allow `auto` for non-static data members.
I understand there are complications in determining the size and layout of objects with auto members, but 18 years later this seems like pretty low hanging fruit compared to what has recently been achieved with reflection!
Edge cases such as recursive definitions and references to this or sizeof should simply be banned rather than resulting in the feature being disabled entirely.
Coroutine workaround
In my quest for a solution I have discovered that coroutines can be abused to get the best of both worlds.
If
I built SpriteForge: A free, lightweight 2D Pixel Editor in C++17 (0% idle CPU, no Electron BS)
Hey everyone!
I was getting tired of heavy, Electron-based tools eating up my RAM just to draw some pixel art and animations, so I rolled up my sleeves and built my own from scratch.
It’s called **SpriteForge**. It's written entirely in modern C++ (C++17) using SDL2, OpenGL 3.0, and Dear ImGui. It's completely free and open-source.
I focused heavily on making it as lightweight, fast, and portable as possible.
Some cool under-the-hood stuff I'm really proud of:
* **0% Idle CPU/GPU Usage:** I hooked up the main loop to `SDL_WaitEventTimeout`. If you aren't actively drawing or playing an animation, the thread goes to sleep. It consumes literally zero CPU/GPU. No laptop heating up!
* **Ultra-Low RAM Footprint:** The undo/redo history engine just stores raw pixel byte arrays of the layers instead of duplicating heavy textures. You can run this comfortably on an ancient 256MB RAM machine.
* **Standalone Portable EXE:** I cross-compiled the Windows version using MinGW-w64 and statically linked the GCC/C++ runtimes (`-static-libgcc -static-libstdc++`). No more "missing libstdc++-6.dll" errors on fresh Windows installs. Just double-click the \~3MB `.exe` and it opens instantly.
* Added a fun, custom cyberpunk "YGCODES" boot splash screen just for the aesthetic. 😃
Features for actual drawing:
* Multi-threaded layer blending (Normal, Multiply, Add, Screen)
* Full animation timeline with Onion Skinning
* Tools: Bresenham interpolated pen (no gaps when drawing fast), stack-safe flood fill, shape tools, etc.
* Built-in retro palettes (PICO-8, DawnBringer)
* Custom `.sforge` binary project saving and SpriteSheet/PNG exports.
I’d love for you guys to try it out, poke around the source code, or use it for your indie games.
Repo link: [https://github.com/YGCODES1/SpriteAnim](https://github.com/YGCODES1/SpriteAnim)
Let me know what you think or if you have any feature requests!
https://redd.it/1tfnhgi
@r_cpp
What do you use for logging in your C++ codebase? What are the pros/cons?
I've used Google's logging library in the past and I would give it a solid B- grade. It gets the job done. I really dislike the streaming operator, but meh it's not that bad. It just feels weird if I concatenate the string beforehand: LOG(INFO) << absl::StrCat(strs...);
As I embark on my new project, I want to make intelligent decisions about what idioms to favor. Logging is a big one, so I'd love to hear what people out there use.
In particular, if there is a library that uses reflection to give named arguments, that would be perfect! My ideal callsite would look like this:
my::LogInfo("Hello, {person}!", {
.person = GetPersonObject(),
});
It would also be cool to get assertions baked into it, though that complicates the design space.
Anyone wanna chime in?
https://redd.it/1tf4rri
@r_cpp
FYI: Class Template Argument Deduction (CTAD) does not compose well with Designated Initializers
I've been playing around with Designated Initializers lately to see if I can use them for robust NAMED function parameters. It seemed promising at first, but I've hit a wall when it comes to type deduction.
Instead of explaining all the steps, I'll just share where things ended up. So to define an API that uses designated initializers and CTAD, you end up with something like this:
struct NotProvided {};
template <
typename Size = NotProvided,
typename Capacity = NotProvided,
typename Factory = NotProvided
\>
struct Params {
Size size = {};
Capacity capacity = {};
Factory factory = {};
};
template <typename T>
struct Vector {
Vector(auto params) {
// ...pick apart the Params object...
}
};
You can and should make use of concepts to give more type information to the caller. Unconstrained templates are not as helpful when debugging, but I'm using them here to clarify the problem.
So given a callsite like this:
int64_t counter = 0;
auto v1 = Vector<int64_t>(Params{
.size = 0,
.capacity = 10,
.factory = [&\](int64_t* addr) {
::new (addr) int64_t(counter);
\++counter;
},
});
This should work fine and was what got me excited about the prospects of things. But once I started actually writing types like Vector and their tests, I kept getting surprising template error messages. One category was the deduction of reference types instead of underlying value types. That alone is infuriating but can be resolved with extra steps.
Instead, the deeper issue has to do with the interaction between CTAD and designated initializers. Consider this callsite:
auto v2 = Vector<int64_t>(Prams{
.size = 20,
.factory = DefaultFactoryFor<int64_t>,
});
This won't work. And the reason why is very upsetting.
When performing Class Template Argument Deduction, it first does an unevaluated invocation a synthesized overload set. That overload set, in this case, looks roughly like this:
Params();
Params(auto size);
Params(auto size, auto capacity);
Params(auto size, auto capacity, auto factory);
Then, when performing this invocation, it just uses the values of the arguments. It does not consider the field names.
So that means...
Params{.size = 10, .factory = DefaultFactoryFor<int64_t>}
... becomes ...
Params{10, DefaultFactory<int64_t>}
... which causes CTAD to select ...
Params(auto size, auto capacity);
Since the assumptions made about `auto capacity` are incompatible with the assumptions made about `.factory` arguments, this fails to compile!
I really wish that CTAD understood the field names when invoked via designated initializers.
I expected the default type values (`NotProvided`) and default member initializers (` = {}`) to work here. I thought it would unambiguously invoke the CTAD `Params(auto, auto, auto)` overload because all the arguments I did not spell (`.capacity`) would be "injected" into the callsite prior to type deduction. But that is not what happens.
If anyone knows a solution to this, I would be very happy.
https://redd.it/1te2yj1
@r_cpp
Windows vs MacOS
I’m new to programming with c++ and I’m currently going through introduction courses on Codecademy.
Is there a major difference with coding on Mac and coding on windows? Like big enough differences to specifically always use one over the other or is this kind of a no brainer question I should already know the answer to.
https://redd.it/1tdhz4f
@r_cpp
LWG 2839 inquiry
I’m working on a string library that wraps std::basic\_string and uses a “rvalue-aware” API pattern:
* const& overload returns a new string
* && overload tries to reuse the existing buffer and returns by value
The intended usage is this kind of chaining:
my_string s = "...";
s = std::move(s).trim();
s = std::move(s).to_lowercase();
I have many cases in which I found performance gains by defining a "create new object" version of a transformation alongside and inplace one and this pattern allows me to reuse method identifiers.
A simplified example looks like this:
struct my_string {
std::string data;
my_string trim() const& {
my_string result;
copy_trimmed_part_to(result); // determine subrange after trim and only copy that part
return result;
}
my_string trim() && {
trim_inplace(); // mutate the current object / reuse buffer
return std::move(*this); // return by value
}
// ...
my_string& operator=(my_string&&) = default;
};
My question is about [LWG 2839](https://cplusplus.github.io/LWG/issue2839), which talks about self-move-assignment.
At first glance, s = std::move(s).trim() feels like it might be related, because the && overload operates on s and then the result is assigned back into s. But the returned object is still a separate prvalue result, even if it reuses the original buffer internally.
So:
1. Is s = std::move(s).trim() actually covered by the self-move-assignment concerns from LWG 2839?
2. Or is LWG 2839 only relevant to direct cases like s = std::move(s)?
3. If the wrapper is built on top of std::basic\_string, is there any subtle standards issue with this API pattern itself?
4. Is the real risk instead overlap/aliasing in APIs like replace, insert, etc. when additional arguments may refer into the same string?
I’m interested both in the strict standards view and in whether this pattern is considered sound library design in practice.
https://redd.it/1tdalnh
@r_cpp
I built a graph database where everything is a fixed‑size node and storage is just an mmap‑ed file - looking for honest feedback
http://github.com/LincolnCox29/TrueGraphDataBase
https://redd.it/1td16em
@r_cpp