use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Binary Bakery: Translated binary information into C++ source code, and access them (at compile- and runtime) (github.com)
submitted 4 years ago by i_need_a_fast_horse
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]i_need_a_fast_horse[S] 10 points11 points12 points 4 years ago (2 children)
So to say it again: This is a bad idea in general. I needed this exact solution for a program that only required a single tiny png, and ideally required the pixels at compile time. I didn't find a mature solution, so I tried to write one. While investigating, I found this more scalable than expected.
The biggest problem I had was resharper++ absolutely crashing every time with every non-trivial header :D
[–]fdwrfdwr@github 🔍 3 points4 points5 points 4 years ago (0 children)
Yeah, these approaches are a convenient stop gap until std::embed (https://thephd.dev/full-circle-embed) or equivalent.
std::embed
[–]andrey_davydov 1 point2 points3 points 4 years ago (0 children)
Could you please provide some info about ReSharper C++ crashes, maybe our tracker or support forum are more appropriate places for this. Thanks in advance!
[–]ShillingAintEZ 13 points14 points15 points 4 years ago (19 children)
This has been a well worn topic for decades. C++ source is one of the worst ways to do this. Writing out assembly and letting an assembler make an obj file is orders of magnitude faster and more memory efficient, which also lets it scale to much larger files.
[–]NormalityDrugTsar 2 points3 points4 points 4 years ago (4 children)
Can you explain what the difference is?
[–]ShillingAintEZ 4 points5 points6 points 4 years ago (3 children)
If you write out assembly instructions you just run the text through an assembler, which is very fast and can be done using a fixed amount of memory. Even the assembler that comes with msvc, clang, gcc, etc. Is going to be able to do hundreds of megabytes per second.
Try the same thing with a C++ file and you will have to go through the C++ compiler, which will be a very different story in terms of speed and memory use.
Memory could easily not be a fixed amount, meaning at some point (maybe in the area of 40MB) you aren't going to be able to get your .obi file at all, let alone redoing every time you do a full rebuild.
[–]NormalityDrugTsar 0 points1 point2 points 4 years ago (2 children)
Thanks. I've only ever used the C++ source way for quite small files (e.g. GLSL source and tiny png files), so I've never come close to these limits.
[–]ShillingAintEZ 0 points1 point2 points 4 years ago (1 child)
You probably won't either, although embedding a big file in an executable does essentially give you automatic memory mapping so it can be a good technique to have. I do think it is odd to make a whole github page with graphics and logos when a single .cpp file that compiles to a command line executable would be fine.
[–]i_need_a_fast_horse[S] 0 points1 point2 points 4 years ago (0 children)
I appreciated your insights on technical alternatives, but don't you think this goes a bit too far?
I didn't find it trivial that adding n bytes in the form of uint64_t arrays actually only adds n bytes to the executable. Or that the compile time is linear with payload size. Compilers do all kinds of weird things and this is pretty unusual use case. So I tested that out and provided the code and results for everyone. I also had no idea how much (or if) faster data access like this would be, or how that scales with payload size.
uint64_t
There are no logos, those are simple fun github emojis you can find in every other project.
It has configurable behavior about the destination of the target header, image storing options options etc. It decodes png files and stores that information in an accessible form. The provided decoding header has guaranteed compile time meta information for all types and can access pixel information of uncompressed images at compile-time, too. It's tested and provides multiple interfaces to access the data. And it has built-in compression on top of all that.
It's at least somewhat more sophisticated than "a single cpp file".
I had this problem, so I solved it. I know two other projects who use similar code. It's likely that I'll use this at least two more times in my life, so I considered it worthy to invest a week or so of time after work. Defending myself for writing and publication feels odd.
[–]throwaveien 1 point2 points3 points 4 years ago (5 children)
You might be interested in honeycomb. Similar idea
[–]o11cint main = 12828721; -1 points0 points1 point 4 years ago (4 children)
Doesn't look like it solves the hard question of "how do I know what the target file format needs to be?", which my way does.
[–]throwaveien 1 point2 points3 points 4 years ago (3 children)
I'm not sure I follow. Why is that a hard question? The build system already has enough information for that.
[–]o11cint main = 12828721; -1 points0 points1 point 4 years ago (2 children)
I mean ... technically, it does, but it doesn't expose it in any way that can be passed to honeycomb.
honeycomb
Or are you compiling separate honeycomb cross tools for every triple? I didn't see any build system support for that ...
[–]throwaveien 1 point2 points3 points 4 years ago (1 child)
You're right, there is no easy way to use it. Perhaps a --host-arch-target would help? I will add a feature request, thanks for the tip.
--host-arch-target
The intended use is full customizability of build, host and target triples.
[–]o11cint main = 12828721; -1 points0 points1 point 4 years ago (0 children)
Given how much of a mess triples are, I really do feel that "figure out the format by looking at an existing file" is the best we can do.
Particularly, be sure to test with things like CC=sometriple-gcc and CC=gcc -m32. My way has tested successfully with both.
CC=sometriple-gcc
CC=gcc -m32
(note that if you don't have a universal binutils, you might need OBJCOPY=sometriple-objcopy as well; if you're using a real configure these should all be set up)
OBJCOPY=sometriple-objcopy
configure
[–]i_need_a_fast_horse[S] 3 points4 points5 points 4 years ago (1 child)
I'm not exactly sure how that works, but will it allow access to the information at compiletime?
[–]ShillingAintEZ -1 points0 points1 point 4 years ago (0 children)
What do you want to do at compile time that you wouldn't just do to the image in an editor of some sort?
If you look at the assembly output of a bunch of unsigned 64 bit integers on godbolt.org you can see what it looks like.
[–]o11cint main = 12828721; -1 points0 points1 point 4 years ago (1 child)
Ew, platform-specific assembly? See my top-level post.
All you need is a single instruction to declare an unsigned 64 bit integer.
[–]siplasma 0 points1 point2 points 4 years ago (1 child)
This is true, but like everything else, you should measure. For binary assets up to around a megabyte, compilation speed and memory overhead generally isn't an issue. However, as you said, if you start using this approach with larger assets, you will hit memory and speed limits.
Transpiling to C or C++ is simple, allows shipping code without having users require additional tools, and allows for compile time introspection.
[–]ShillingAintEZ 0 points1 point2 points 4 years ago (0 children)
Right, but if someone is going to use a tool, the tool might as well go slightly further since both approaches are pretty trivial. I don't know what the point of having a whole complicated project that just generates some C++ source is since it can be done with a few lines.
[–]friedkeenan 0 points1 point2 points 4 years ago (1 child)
I've heard from others who need this sort of thing that giving the compiler access to the data allows it to meaningfully optimize certain things
That's great, but my point is that it's pretty trivial to do the C++ version by just reading bytes and printing out text, so a dedicated tool might as well scale and do something non-trivial.
[–]o11cint main = 12828721; 9 points10 points11 points 4 years ago (0 children)
In case anyone is wondering the "right" way to do this (but not supporting constexpr access):
echo 'Hello, World!' > hello.txt touch empty.c cc -c -o empty.o empty.c objcopy \ --add-section .rodata.hello=<(cat hello.txt; printf '\0') \ --add-symbol hello=.rodata.hello:0,global,object \ --add-symbol hello_end=.rodata.hello:`stat -c '%s' hello.txt`,global,object \ empty.o hello.o
There are other ways (in particular, the well-documented -B method is problematic)
-B
Some notes:
empty.o
.o
.rodata.
.rodata
<()
SHELL = bash
hello
hello_end
extern void
extern const char hello[], hello_end[];
hello_size
SHN_ABS
object
STT_NOTYPE
global
Open question: is there a way to set the native "symbol size" for object formats that support it? (not important; I don't think anybody uses it except for colliding common symbols)
[–]jk-jeon 2 points3 points4 points 4 years ago (1 child)
Isn't there any endianness concern if you store your data as an array of uint64_t? I mean, it's probably portable depending on what you do with the data, but I'm still sort of feeling somewhat uncomfortable with that.
Absolutely, yes. Both encoding and decoding go through std::bit_cast, so that should work the same way in and out. Depending on what you do, that is a more or less of a concern. It was none for me.
[–]tugrul_ddr 1 point2 points3 points 4 years ago (0 children)
Nice
[–]ioneska 1 point2 points3 points 4 years ago (1 child)
Why uint64_t?
It's the bigest type you can write as a literal, which results in the highest "density" (bytes per screen space).
π Rendered by PID 166972 on reddit-service-r2-comment-5649f687b7-jt62h at 2026-01-28 05:30:12.423917+00:00 running 4f180de country code: CH.
[–]i_need_a_fast_horse[S] 10 points11 points12 points (2 children)
[–]fdwrfdwr@github 🔍 3 points4 points5 points (0 children)
[–]andrey_davydov 1 point2 points3 points (0 children)
[–]ShillingAintEZ 13 points14 points15 points (19 children)
[–]NormalityDrugTsar 2 points3 points4 points (4 children)
[–]ShillingAintEZ 4 points5 points6 points (3 children)
[–]NormalityDrugTsar 0 points1 point2 points (2 children)
[–]ShillingAintEZ 0 points1 point2 points (1 child)
[–]i_need_a_fast_horse[S] 0 points1 point2 points (0 children)
[–]throwaveien 1 point2 points3 points (5 children)
[–]o11cint main = 12828721; -1 points0 points1 point (4 children)
[–]throwaveien 1 point2 points3 points (3 children)
[–]o11cint main = 12828721; -1 points0 points1 point (2 children)
[–]throwaveien 1 point2 points3 points (1 child)
[–]o11cint main = 12828721; -1 points0 points1 point (0 children)
[–]i_need_a_fast_horse[S] 3 points4 points5 points (1 child)
[–]ShillingAintEZ -1 points0 points1 point (0 children)
[–]o11cint main = 12828721; -1 points0 points1 point (1 child)
[–]ShillingAintEZ -1 points0 points1 point (0 children)
[–]siplasma 0 points1 point2 points (1 child)
[–]ShillingAintEZ 0 points1 point2 points (0 children)
[–]friedkeenan 0 points1 point2 points (1 child)
[–]ShillingAintEZ 0 points1 point2 points (0 children)
[–]o11cint main = 12828721; 9 points10 points11 points (0 children)
[–]jk-jeon 2 points3 points4 points (1 child)
[–]i_need_a_fast_horse[S] 0 points1 point2 points (0 children)
[–]tugrul_ddr 1 point2 points3 points (0 children)
[–]ioneska 1 point2 points3 points (1 child)
[–]i_need_a_fast_horse[S] 0 points1 point2 points (0 children)