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,428
  • 1
  • 10
  • 25
  • 4
    Why do people eat chocolate ice cream instead of vanilla? The answer to that question is equally rational. Software developers also routinely ask the `i++ + ++i` question on Stack Overflow, even though it is pointless. Nobody knows where this question comes from, and it always leads nowhere ("nowhere" being defined as undefined behavior and "never write code like this"). – Robert Harvey Jul 05 '20 at 23:24
  • @RobertHarvey Well, that's what I'm asking. Just because I cannot see any good use case does not make me assume that there is none. – klutt Jul 05 '20 at 23:26
  • I think you can safely assume that there is no reasonably good use case for this. Don't assume that software developers are any more rational than those in other professions. Software developers still believe in "one entry, one exit," even though that concept was [debunked decades ago](https://softwareengineering.stackexchange.com/a/118793/1204). So take heed: you don't need our confirmation for something that you already know perfectly well is bullshit. – Robert Harvey Jul 05 '20 at 23:30
  • If you're still not convinced, your valid use case is "whenever you need to use malloc while compiling a C program with a C++ compiler." The only usable tidbit of information here is that the cast makes it possible. So one day, when you come across that exquisitely rare situation where maybe the company you work for only allows the Zenon Zephyr C++ compiler with C code, you'll be able to do it, because you know about the cast. I've seen stranger things happen. – Robert Harvey Jul 05 '20 at 23:33
  • 2
    This is discussed at great detail in this Stack Overflow [question](https://stackoverflow.com/q/605845/5231607). – 1201ProgramAlarm Jul 06 '20 at 00:56
  • @RobertHarvey Ok then, they I guess you could write an answer :D – klutt Jul 06 '20 at 01:40
  • @1201ProgramAlarm Well, it is mentioned in the discussion, but the question is about casting malloc and not writing C++ compatible code in general – klutt Jul 06 '20 at 01:41
  • 5
    Well, you could be using a C library in a C++ program. – GrandmasterB Jul 06 '20 at 02:42
  • Perhaps if your platform is a Microsoft one, which has a very out-of-date C compiler but a relatively modern C++ compiler. – user253751 Jul 06 '20 at 10:22
  • Most of those *nice new features in modern C* are so riddled with undefined-, unspecified- and implementation-defined behaviours that they are unwise to use in any high-integrity system – Andrew Jul 06 '20 at 13:21
  • 1
    It depend on project that developer working on. If they are working on a kernel, they do not have support for most of what C++ has.it looking like C. outside the kernel, the support for the rest of C++ is available - which can make applications easier to write. – AjayGohil Jul 17 '20 at 06:10

6 Answers6

10

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
  • 42,090
  • 4
  • 59
  • 119
  • 1
    How can it be "better than plain C" if you're not allowed to use any of the C++ specific features? – klutt Jul 06 '20 at 12:23
  • 3
    @klutt. A stronger type system. For the same code, a C++ compiler is more likely to catch an error then a C compiler. – Nemanja Trifunovic Jul 06 '20 at 12:35
  • @NemanjaTrifunovic Well, that's true, but then what's the reason of restricting yourself to make it compile as C? Why not just use C++? – klutt Jul 06 '20 at 14:56
  • Because you _want_ to use an incremental improvement to C, and not a whole new language with new idioms. We could call it `C+1`, or `++C`, or ... – Useless Jul 06 '20 at 15:04
  • @Useless I could understand that if you want to avoid the very fancy new features like smart pointers and stuff. But I don't see the point in restricting yourself to not even use a single feature that is not also valid C. – klutt Jul 06 '20 at 15:12
  • Perhaps you have some existing C code? Is it really that hard to believe that someone might want to add some type safety to C without re-writing the whole thing? – Useless Jul 06 '20 at 15:14
  • @Useless But you don't have to rewrite everything, which is my point. There's nothing very wrong with mixing `printf` and `std::cout`. Please also note that I'm not saying that it would be something strange with prefering `printf` instead of `std::cout`. I do it for instance. But then I would choose `printf` because I consider it better, and not for being able to compile with a C compiler. I perfectly understand why you want to add the type safety. What I don't understand is why you want the code to compile as two different languages. – klutt Jul 06 '20 at 15:26
  • So you have an existing C (or C-style) codebase, you're not rewriting everything ... how is that not "using C++ as a better C"? Nobody said they would _also_ keep building with the C compiler, so I don't really know what you disagree with. – Useless Jul 07 '20 at 14:25
  • 4
    Look up “pragmatic” in the dictionary. It’s a very important word. It’s the opposite of “dogma”. – gnasher729 Jul 07 '20 at 15:41
  • @Useless It's my fault. I was not specific enough when I wrote the question. What I intended to ask was why some coders make sure that all their code is both valid C and C++. – klutt Jul 08 '20 at 12:56
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
  • 102,279
  • 24
  • 197
  • 315
Kain0_0
  • 15,888
  • 16
  • 37
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
  • 10,826
  • 1
  • 31
  • 43
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.

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
  • 199,015
  • 33
  • 367
  • 565
  • In the case of coding in the common subset of C (some version) and C++ (some version), one has to admit that the single valid reason for doing so for implementation files (compiling everything at once for whole-program-optimization) has been overtaken by implementation improvement (lto anyone?). Are you aware of any platform where you have a C++ compiler but not a C compiler, even if for an older version? – Deduplicator Dec 18 '21 at 13:43
  • @Deduplicator: In the embedded systems world, some code may need to be able to run on multiple platforms, some of which have reliable C++ compilers available and some of which do not. – supercat Aug 10 '23 at 21:35
  • @supercat The point is that there is no platform having a good C++ but no C compiler. And calling C code is easy from both. – Deduplicator Aug 10 '23 at 23:10
  • @Deduplicator: I don't know of any C++ compilers for the PIC family; my biggest piece of dual-mode code was used to run as C++ on MSVC and as C code on the PIC. Also, while I've not tried linking clang/gcc-generated object files with e.g. Keil, processing everything wiht one compiler seems easier than using two. Yes, I know later versions of Keil presumably support later versions of C++, but I think that's only when using the clang-based versions which I don't view as trustworthy. – supercat Aug 11 '23 at 15:40
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
  • 10,840
  • 3
  • 23
  • 32
  • 2
    There is no type mentioned in `p = malloc(n * sizeof *p);`. How can you be more explicit than that without appreciably increasing the likelihood of bugs? – Deduplicator Jul 07 '20 at 20:17