← Back to context

Comment by Panzerschrek

8 hours ago

I don't understand people reinventing macro-based hacks in C to achieve what was achieved in other languages many years ago. Why not using C++, for example? It's available almost everywhere, introducing its usage in an existing C codebase is pretty simple. Sure, C++ has its own downsides, but is it better to create mess with macros in C rather then using exiting language facilities and standard library containers provided by C++?

Having used C++ a lot in the past, I think the mess in C++ is way worse. I also contribute to projects that introduce C++ into a C code base, and I really wish they hadn't done this.

Although there are C features I like that I would need to remove before introducing C++ to a codebase, so this may not always be so simple.

  • > the mess in C++ is way worse

    What is mess in C++? Yes, it has some shady parts and is more complex than C, but this complexity provides expressiveness and type safety. And you can always use only features from C++ you find useful.

    > also contribute to projects that introduce C++ into a C code base, and I really wish they hadn't done this.

    What is problematic in these projects other than unfamiliarity of C++ for developers previously used only C?

    • > What is mess in C++?

      Just a couple examples:

      How do you make a shallow copy of an object in C++, how do you do the same thing in C? Knowing I can just memcpy _any_ struct in C and have a valid shallow copy is pretty huge.

      How do you create a stable ABI in C++? How do you make one in C? In C, knowing that all my exported functions will mostly just work and be stable as long as I don’t change the interface is also huge and allows you to create cross language bindings pretty trivially.

      5 replies →

    • > And you can always use only features from C++ you find useful.

      Ah, the old "programmers just need to be more disciplined when using C++".

      Yeah, C programmers have never seen that argument before...

      1 reply →

For one reason, it is because C++ runtime (and its standard library) is a whole own can of worms which most people would rather not touch if they can afford to. Which they mostly can.

> Sure, C++ has its own downsides

"Sure, getting your eyes gouged out has its downsides, but is it better to read that awful mess of macros in C instead?" The answer most people would give to this question may surprise you.

  • Here we go again. Yes there are bad parts in the C++ standard library and there are good parts. But if you are just trying to do type safe generic data structures you are unlikely to touch the bad parts. Many codebases forbids parts of the standard library, e.g. LLVM forbids including <iostream>. You can forbid using parts of the standard library too.

    • > Yes there are bad parts in the C++ standard library and there are good parts.

      Okay, other than <vector>, what are the good parts? Because as the sibling comments rightfully point out, migrating your codebase from C to C++ just to be able to use <vector> is not worth it.

      The <map> is a sad joke played upon the C++ programmers by the standard committee.

      13 replies →

Its rather hard to introduce c++ into legacy c projects. You basically have to decide on a subset of features to use, and then you'll have to explain to the teams why the same looking code now takes 10x more compute to build.

Usually the way we do it here is we honor some interface then rewrite the subsystem in c++.

And then there's the real hurdle and that is getting the c++ idiom correct as it is very easy to just open the floodgates and let everyone write code that looks vastly different.

I'd rather not migrate my C codebase to C++ just to use an array container. Very hard to consistently limit the codebase to a strict subset of C++.

  • It is called a linter, more devs should learn to use a tool that was originally created for C in 1979.

    • The only decent linters I know of for C++ are clang-tidy and coverity and they are not good enough.

Not sure why author does it, but I use C over C++ for one reason: I'd rather not have random hidden malloc() scattered in my code. And no, it's not about latency or performance. Once my code takes an yet unexplored part and runs out of 200kB RAM, the will be no way for me to learn about it - running out of memory will bring down both the logger and the radio link, which is the only way to get the logs from a sensor installed twenty meters above ground in a hazardous environment facility. C may be unsafe, but most errors short of "writing to a random memory area" are either well-contained or at least reproducible. Dynamic memory allocation means that anything may crash everything. Manageable if you have a MMU and can contain crashes within isolated heap, but if not - I'd rather not bother. And yea, you can write zero-allocation C++ code, but why bother if most of STL is now unusable? And you get some new and exciting UB modes (seriously, no union aliasing, what the heck?)

Also, template metaprogramming is way more arcane than C macros. And I need compile-time metaprogramming in leu of dynamic allocation. So C macros it is for now (Zig is promising but still not there yet).

STL is amazing and the people that designed it were very smart.

Problem is C++ has many features which I likely won't be able to understand in this lifetime. But using C-style C++ is nuts.

Just the extra of STL is basically the C that C should have been. It's a shame not to have a string type or use brittle macros.