10

In discussions about whether to cast the result of malloc or not when coding C, one common argument is that if you cast the result then you can compile your C code with a C++ compiler.

Why would one ever want to do that? If I'm not mistaken, there are C compilers available for almost any platform imaginable, but the opposite is not equally true.

So why do people want to compile their C code with a C++ compiler? Why not just use a C compiler instead? C is tricky enough as it is. Keeping track of all the details that would ensure that it's equivalent (nut just valid) C++ code can be quite tricky, especially since there are quite a lot small things that are valid in both languages, but mean different things. Furthermore, it also makes it impossible to use some of the nice new features in modern C.

So what is the use case of coding "C-style C++"?

klutt
  • 1,438

6 Answers6

8

Lots of people use C++ as “better C”. And there’s nothing wrong with that. It’s something that’s still very easy to understand for someone who learned only C, and that is better than plain C.

So there’s nothing wrong with writing C code that compiles identical as C++ code.

gnasher729
  • 49,096
6

Habit

Back in the day everyone was a C/Fortan/Lisp programmer - and when they moved to other languages complained about this feature, or that restriction. What you got were programs looking like C/Fortran/Lisp just not written in C/Fortan/Lisp.

Now days many C++/Java/Haskell/etc.. programmers now have to write C code. And complain about the this feature, or that restriction. What you get are programs looking like they were written in C++/Java/Haskell/etc... just not written in C++/Java/Haskell/etc...

Perhaps I'm already out of date on who the programmers are. I hear there is this upstart language called JavaScript. Wonder if anyone is going to start writing programs that way, that aren't written in JavaScript. Wait...

Same music different singers.

Legibility

Turns out that writing a cast in front of a malloc lets you be very clear what the malloc is mallocing, even if the malloc is split from the variable declaration as I believe (at least historically so) C variables must be declared in advance of scoped operations, which isn't always where you want to perform allocations. Last time I checked casting a pointer is perfectly valid C.

My hunch is that people try to rationalise this by claiming interoperability (which it surely supports), but they are really trying to write code that is clear to the audience who is going to read it. Now days many C programmers are also C++ programmers, and C++ programmers are habit driven to specify type in an allocation (I'm looking at you new T()).

candied_orange
  • 119,268
Kain0_0
  • 16,561
3

The one use case I consider halfway valid is that you are transitioning from C to C++, and you are temporarily using C-style memory management to minimize the amount of work; basically, a lift-and-shift operation.

Then, once you have it building and running as C++, you gradually change out the C-style memory management for the more robust C++ features.

John Bode
  • 11,004
  • 1
  • 33
  • 44
2

Why are people coding “C-style C++”?

Historic inertia.

When C++ arrived, it was quite successful - a big hit. A lot of transitions of C code to C++ could be done with little re-work. Dual C/C++ development/maintenance was initially possible. C++ was looking to not be just another language, but a successor to C as ever increasing classes appeared.**

Importantly C itself was paused in it development to allow steady C to C++ transitions to continue and C++ to mature without playing catch-up with C.

But C did not get subsumed. C99 hit with VLA, FAM, long long, restrict, and hurt that compatibility model. C marched ahead with attributes not found in C++. C and C++ diverged significantly since then and with C11. C++ marched away too from C with template fever. The parent and child no longer live in the same house.

Yet for many, the model of transitional compatibility persisted. MS today only includes in their C89-ish C, C99/C11 features found in C++. My experience with professors on Stackoverflow see the educator community continue to push for a C using only common features. There is much inertia.

So what is the use case of coding "C-style C++"?

It is a use case that diminishes each year with major steps apart with each C release. IMO, since C11, it is just gone.


** Early C++ coding was a translator from C++ source to C source and then to a compiler. Thus anything done in C++ could be done in C - just a question of ease.

chux
  • 638
2

Writing code which can be compiled with a C and C++ compiler as well simply extends the number of projects and cases where the code can be reused. You asked

Why not just use a C compiler instead?

Well, in several C++ projects people would be pretty hesitant to use two different compilers, since it would complicate their setup. Now imagine the case where a piece of code is used and maintained mainly in a C environment, but with the option of also reusing it in another project which works with C++. That would be a good match for writing C-style C++.

Sometimes, developers love to do such things "just in case", not knowing if there will be ever a C++ project where the code will be reused - and this is where things become questionable.

Doc Brown
  • 218,378
1

The main reason I can think of is other people.

There are a lot of C++ programmers out there. If your software ever might get touched by one of them, it makes their life easier if you use the common portions of the languages when possible.

There's also the case where you are compiling someone's library into your own program. Many times the build tools will handle the C vs. C++ differences correctly. Other times, it's a bit of a pain. Much easier if one uses the common portions of the languages.

And in the particular case of malloc, its more explicit to use the cast. Many programming style guides recommend explicitness when it comes to memory management because the cost of debugging a mistake in memory management is so brutal.

Cort Ammon
  • 11,917
  • 3
  • 26
  • 35