Wed 31 December 2025

🌫️ Sane C++ December 25

SC

Welcome to the December 2025 update!
This month the Http library is finally losing its dependency on Memory and gets a lot of reliability fixes!

Dependencies

The bulk of work for this month has been getting rid of the Memory dependency from the Http library.

This is incredibly important, because allocation is only done by the Memory library!

This means that excluding Containers and the support ContainersReflection all libraries make No allocation whatsoever. All of them can work inside fixed buffers or inside dynamically allocated memory allocated by the user that has knowledge of the entire application context.

Plus, it finally makes the internal dependencies graph between all libraries look super cool:

Http

Going back to the actual improvements to Http, I am not sure where to start. Multiple iterations of the API have been done and it's probably not over yet...

The API at the beginning of the month was something like this, with allocating Buffers usage and raw allocations everywhere (so ugly!):

The point has been making sure that a connection should be able to live within a block of memory that is fixed during its initialization.

This is because most of the time, reasonable defaults and safety limits must be set anyway to control how many Kb of headers can be accepted or how many Kb can be dedicated to streaming large files.

One example on initializing the web server with compile time fixed buffers is the following:

As AsyncStreams have been fully integrated, it's now possible to send even very large file using some tiny fixed buffers. If they're too tiny, the transfer is going to become very slow, as a lot of syscall will be needed to fully transmit the file, so it's always as good idea sizing the buffers accordingly.

If one wants to decide the size of these buffers at runtime, the API will become slightly more verbose but I would say it's not so bad:

The example shows how to assign memory from Structure Of Arrays style arrangement for these buffers, all equally sized. This is using an helper class called StableArray that uses VirtualMemory to reserve space for extremely large buffers and just commits to physical RAM the actually used quantity. The WebServerExample in SCExample also shows how to resize such buffers at runtime, while the web-server is running!

It's also possible to just give each connection a buffers of different sizes, making the memory management slightly more complicated.

The library is still in 🟥 Draft state, and it will likely stay like that for the next months.

I can still see some random lost connections in browser tools from Safari / Firefox / Chrome when trying to visit some test website.

Also the performance / latency looks quite bad for now, but it doesn't make sense to start working on performance before becoming compliant with the spec to some acceptable level!

Detailed list of commits:

AsyncStreams

A few changes in AsyncStreams have been made, as consequences of Http improvements.

Writable streams can now be destroyed and pipelines are automatically un-piped after all sinks have finished writing their data.

A few fixes also have been applied, like copying listeners during emit event (to allow changing listeners when inside an handler), emptying the read queue on destroy and resetting the request state on init.

Methods to set queues and buffers for the pool have been separated from initialization, so that they can be set during construction / setup and re-used across multiple successive initializations.

Detailed list of commits:

Async

The extensive testing and improvements of Http library has exposed some issues in Async.

A quite nasty bug in the gather writes has been fixed in Posix, affecting partial writes, that has never been surfacing in the unit tests.

Also it made sense to ignore reporting errors when cancellations fail to submit on windows. This happens when trying to cancel an async operation that has already finished but for which the overlapped status has not been retrieved yet.

Detailed list of commits:

Others

The usual mix of fixes this month includes a debug visualizer for Span<T> and properly support exporting types across dynamic libraries (by adding SC_COMPILER_EXPORT in all relevant places).

During a bad search and replace done a few months ago, Result lost its [[nodiscard]] status, that has been fixed.

GrowableBuffer has now a Span<char> specialization, to allow using things like StringFormat / StringBuilder with raw char arrays.

VirtualMemory class has been cleaned up and improved, with its destructor properly releasing allocated memory.

A bug in Process was reading incomplete output from child processes terminating very quickly.

Detailed list of commits:

See you next month!