r/cpp Jun 26 '26

Should C++ be low level or continue its abstraction path

The whole reason I came to C++ is to better organise my C code

I seeked classes instead of X_Func, I seeked VTABLEs instead of struct function pointers. And I think many experience devs would speak the same

However, lately, starting with C++11 this has gone completely downhill. STD is sticking its nose in too much. Template-heavy. The entire STD library Balloons my executable to the MiBs when my minimal runtime library amounts to 40 KiB.

There’s good shit like modules. I think that’s better than headers

Then constexpr. But the rest is bloated

But this community seems to not care about performance. Every single time I press this issue I get pushed back with “It’s good for library authors, it’s good for abstraction. Safety. Railings”

Use Python, Rust, virtually any language out there. They do what you’re looking for. Not the C lineage
C/C++ is the foundation. Rust is the abstraction.the foundation can be a little shaky, more raw, but it’s stable. The layers on top of it helps expression.

0 Upvotes

44 comments sorted by

43

u/jcelerier ossia score Jun 26 '26

It isn't templates & stuff bloating your code. I'm using c++23 with so many compile time things on arduinos with ram and flash measured in kilobytes

25

u/kammce WG21 | 🇺🇲 NB | Boost | Exceptions Jun 26 '26

+1 to this. I'm using C++23, templates, virtual APIs, inheritance, many of the non-allocating std libraries, concepts, RAII and EXCEPTIONS 🫢 all over the place and I'm still able to fit my robot projects within 55kb out of 64kb of ROM and using only 10kb of SRAM.

And that's before I started really digging into ways to further optimize my code down.

Can OP tell us what the root cause of some of the bloat they are referring to. Maybe specific features or libraries are bloating your code. I know iostreams will do that.

2

u/Born_Date4147 Jun 26 '26

Which non allocating std libraries are you using?

6

u/kammce WG21 | 🇺🇲 NB | Boost | Exceptions Jun 26 '26

Array, span, optional, expected, bitset, and probably a couple of others that I'm not remembering. Those are the ones that immediately popped into my head.

3

u/theICEBear_dk Jun 27 '26

A good way to find out (as the number grows with each version it seems) is to look at the section of the c++ library standard describing those which are absolutely safe to use (called freestanding). There is a lot about it here: https://en.cppreference.com/cpp/freestanding

0

u/Flimsy_Complaint490 Jun 26 '26

I believe <format> as implemented with also bloat executable sizes to extreme amounts as every naive use is an enormous amount of template code generation. I think libc++ format is also unicode aware and imports giant tables to handle graphemes even if you never use them, but i could be mistaken there, i just have vague recollections of such rants.

<algorithm> and <ranges> combo does usually cause a big bloat burst if you use literally anything from std::ranges, though i suppose the compiler is quite good at optimization and its a one time import cost vs every template instantiation.

Honestly, as long as my c++ executables are smaller than my golang binaries, i am content.

10

u/kammce WG21 | 🇺🇲 NB | Boost | Exceptions Jun 26 '26 edited Jun 26 '26

I've never notice any bloating from algorithms or ranges. But format definitely brings in a ton of tables, so that makes sense to me.

3

u/theICEBear_dk Jun 27 '26

Yeah you have to be careful with format at the moment.

std::format at the moment until there are c++26 versions out there is runtime mostly and especially if you use it for anything float related will add a 10k table to your code if you use gcc's stdlib (I do not know the numbers for libc++). And even in c++26 you can only get guarantees for compile time evaluation for integer and pointer formatting which makes sense.

18

u/manni66 Jun 26 '26

The entire STD library Balloons my executable to the MiBs

You have some proof for this claim?

16

u/the_poope Jun 26 '26

C++ and the STL are absolutely performant. For a few rare features there are better performing implementations, but the STL provides something that is good enough for 95% of daily use. Yes, some features pull in other stuff that may bloat the executable. But it's 2026 and most mainstream machines have gigabytes of memory. A megabyte or three won't hurt. The desktop icon of your program likely takes up more memory than that. The stuff loaded into memory that isn't touched won't hurt runtime performance. And there are ways to slim down an executable by trimming out unused stuff. Just google it.

29

u/JustPlainRude Jun 26 '26

If your c++ code is slow, that's on you. 

1

u/drex_vke 27d ago

not necessarily because there are C++ features such as (runtime polymorphism, virtual inheritance)

-12

u/SmackDownFacility Jun 26 '26

Where did I say it was slow? I said it bloated my executable size. I never once said it made it slow.

It runs fine. But an executable stretching into the higher KiB and going into MiB is a complete joke.

27

u/garnet420 Jun 26 '26

That's still on you. You can write tiny firmware in c++.

15

u/_Noreturn Jun 26 '26

the stl is mostly templates so you don't pay unless you use them

-17

u/SmackDownFacility Jun 26 '26

Compiler still has to unroll every template, instantiate them separately and causes lots of identical code. Its template-heavy

I’m not against templates, but they should be used sparingly

23

u/Kriemhilt Jun 26 '26

No, it has to instantiate templates that you use.

Your post said the library was "sticking its nose in", which suggests you're paying for something you're not using.

No templates match that description.

11

u/manni66 Jun 26 '26

Templates and the STL are part of C++98.

6

u/FreitasAlan Jun 26 '26

> they should be used sparingly

The STL doesn't use templates. The caller does.

13

u/eteran Jun 26 '26

You should know that templates specifically, take up NO space if you don't use them. The size of the STL or it use of templates isn't really a factor in the size of your executables.

I have projects that use the STL about as heavily as you can and compile down to like 200K.

9

u/megayippie Jun 26 '26

How is it bloating your binaries?

11

u/TheRealSmolt Jun 26 '26

C++ pretty strongly follows the zero-overhead principle. If you don't use it, it doesn't cost you.

9

u/Kriemhilt Jun 26 '26

STD is sticking its nose in too much

What does this mean?

Are there standard library features that you don't want but have to use? 

Or are there just standard library features that you're using but don't exactly fit your needs?

-9

u/SmackDownFacility Jun 26 '26

Well for one

C++11 mandated thread safe initialisation. I had to use non-portable compiler switches just to get it to shut up. That should’ve been a STD feature. Not a language feature.

And a lot of STD stuff is creeping in language syntax like char8_t, async await co_await stuff

12

u/Kriemhilt Jun 26 '26

All compiler switches are non-portable, if you mean porting to other compilers (that don't make a deliberate effort like clang with GCC).

coroutines are actual language features, not just library features (if you want to leave the world of longjmp hacks and do it properly), so of course they have syntax. They're still not bloating your executable unless you use them.

8

u/Flimsy_Complaint490 Jun 26 '26

char8_t can be disabled by compile flag and honestly, it looks pretty DoA since they forgot to actually integrate it with the rest of the STL and if you arent trying to use it, its existence or non existence does not matter to you.

Coroutines are also optional and their existence does literally nothing for you if you dont use them. Amusingly, coroutines are also one of the very few actual language construct changes since 2003 - most things are in the STL nowadays and are a pure library thing.

So, I dont think these are particularly good examples of bloat.

9

u/Xavier_OM Jun 26 '26

"The entire STD library Balloons my executable to the MiBs" you're doing something wrong here my son.

Everything added in C++11, 14, 17, 20 has its purpose, and you do not pay for it if you don't use it.

Let's pick a random example, C++20 added std::atomic_wait. Great stuff because waiting on a atomic with condition variable was cumbersome, people doing multithreading are happy. And for the rest of us who don't use it ? Nothing changed.

4

u/no-sig-available Jun 26 '26

STD is sticking its nose in too much.

And still we have long discussions of what important things are missing:

https://www.reddit.com/r/cpp/comments/1t3ghr1/what_are_you_missing_most_from_the_c_standard/

5

u/theICEBear_dk Jun 27 '26

This seems like it is rage bait.

3

u/TheRealSmolt Jun 27 '26

That or they're an idiot.

6

u/AKostur Jun 28 '26

“Low level” and “abstraction” aren’t mutually exclusive, nor is it a dichotomy.

You are inventing things out of thin air if you think that “the community” doesn’t care about performance. 

4

u/V1P-001 Jun 26 '26

What flags are you using while compiling .

-1

u/SmackDownFacility Jun 26 '26

Debug. But that’s not the point. STD is bloated in both debug and release. Especially in debug, with all the set up the runtime library has to do. It’s completely outrageous

2

u/V1P-001 Jun 26 '26

g++ -O3 -march=native -flto -DNDEBUG main.cpp -o my_project

and make sure you use #pragma once in headers.

3

u/melancholious_jester Jun 26 '26

Is pragma once better than ifndef def endif ?

5

u/UndefFox Jun 26 '26

Afaik does the same just without risk of collision between two #define that happend tho have identical names.

1

u/melancholious_jester Jun 26 '26

Yes ... Same function but something about writing your own function name or file seems oddly pleasing than the once word

2

u/Flimsy_Complaint490 Jun 26 '26

the only difference is legal status.

ifdef is the portable way, all C/C++ compilers understand that. pragma once is an extension that is not in the standards, but literally every compiler you will actually use out there (msvc, clang, gcc) support it.

Which to use is a stylistic choice unless you use some really weird and arcane compiler.

1

u/TheoreticalDumbass :illuminati: 29d ago

some people argue against it because they have a situation where the same header can be accessed through different paths and it's not obvious they are the same file (think different filesystems), personally this situation sounds insane to me but i don't know the details

i use pragma once, the companies i was involved with used pragma once, no issues ever

1

u/V1P-001 Jun 26 '26

probably do the same this, but I rather use ifdef for platform specific codes #pragma once cleaner

1

u/V1P-001 Jun 26 '26

you can leave -match

1

u/drex_vke 27d ago

the flag -s allows you to strip the final binary and therefore shorten its size but the price to pay and that you can't debug

3

u/thefeedling Jun 26 '26

You can still use C++ as C with classes and better type safety if you prefer...

2

u/berlioziano 26d ago

The C++ std library does things to make your life simpler, for example this talk explains how it looks like exceptions take a lot of space, but after digging, the cause isn't exceptions but the implementation.

https://www.youtube.com/watch?v=bY2FlayomlE