6 ms·
>Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up" Where "mixing C/C++" is helpful: - I "mix C in with my C++" projects because "s
by jasode 2y ago
>Takeaway #1: "C and C++ are different: don’t mix them, and don’t mix them up"
Where "mixing C/C++" is helpful:
- I "mix C in with my C++" projects because "sqlite3.c" and ffmpeg source code is written C. C++ was designed to interoperate with C code. C++ code can seamlessly add #include "sqlite3.h" unchanged.
- For my own code, I take advantage of "C++ being _mostly_ a superset of C" such as using old-style C printf in C++ instead of newer C++ cout.
Where the "C is a totally different language from C++" perspective is helpful:
- knowing that compilers can compile code in "C" or "C++" mode which has ramifications for name mangling which leads to "LINK unresolved symbol" errors.
- knowing that C99 C23 has many exceptions to "C++ is a superset of C" : https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B#Constructs_valid_in_C_but_not_in_C++ https://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B...
- accelbred 2y agoC++ can seamlessly include C89 headers. The C library headers for libraries I write often include C11/C99 stuff that is invalid in C++. Even when they are in C89, they are often incorrect to include without the include being in an `extern "C"`.
- nuancebydefault 2y agoExtern "C" around the prototypes is mandatory, otherwise your linker will search for C++ symbols, which cannot be found in the C libraries you pass it.
- accelbred 2y agoNot only prototypes but typedefs with function pointers as well.
- Conscat 2y agoClang supports C11 - 23 in C++, as well as some future C features like fixed-point integers. The main pain points with Clang are just the fundamental differences like void* and char, which don't typically matter much at an interoperability layer.
- flohofwoe 2y agoThere's a lot of subtle differences between 'proper' C and the C subset of C++, since C++ uses C++ semantics everywhere, even for its C subset. Many C++ coders are oblivious to those differences (myself included before I switched from 'mainly C++' to 'mainly C') because they think that the C subset of C++ is compatible with 'proper' C, but any C code that compiles both in a C++ and C compiler is actually also a (heavily outdated) subset of the C language (so for a C coder it takes extra effort to write C++ compatible C code, and it's not great because it's a throwback to the mid-90s, C++ compatible C is potentially less safe and harder to maintain). For instance in C++ it's illegal to take the address of an 'adhoc-constructed' function argument, like: sum(&(bla_t){ .a = 1, .b = 2, .c = 3, .d = 4 }); (godbolt: https://www.godbolt.org/z/r7r5rPc6K https://www.godbolt.org/z/r7r5rPc6K) Interestingly, Objective-C leaves its C subset alone, so it is always automatically compatible with the latest C features without requiring a new 'ObjC standard'.
- pjmlp 2y agoBecause Objective-C initial proposal is that everything that isn't touched by Smalltalk like code, clearly in brackets or @annotarions, is plain C. The pre-processor original compiler, before the GCC fork, would leave everything else alone, blindly copying into the generated C file.
- kccqzy 2y agoYeah plenty of headers first have `#ifdef __cplusplus` and then they add `extern "C"`. And of course even then they have to avoid doing things unacceptable in C++ such as using "new" as the name of a variable. It takes a little bit of an effort to make a header work on C and C++. A lot less effort than making a single Python file work with Python 2 and 3.
- flohofwoe 2y agoThe '#ifdef __cplusplus extern "C" { }' thing only removes C++ name mangling from exported symbols, it doesn't switch the C++ language into "C mode" (unfortunately).
- tialaramex 2y agoThe entire I/O streams (where std::cout comes from) feature is garbage, if this was an independent development there is no way that WG21 would have taken it, the reason it's in C++ 98 and thus still here today is that it's Bjarne's baby. The reason not to take it is that it's contradictory to the "Don't use operator overloading for unrelated operations" core idea. Bjarne will insist that "actually" these operators somehow always meant streaming I/O but his evidence is basically the same library feature he's trying to justify. No other language does this, and it's not because they can't it's because it was a bad idea when it was created, it was still a bad idea in 1998, the only difference today is that C++ has a replacement. The modern fmt-inspired std::print and std::println etc. are much nicer, preserving all the type checking but losing terrible ideas like stored format state, and localisation by default. The biggest problem is that today C++ doesn't have a way to implement this for your own types easily, Barry illustrates a comfortable way this could work in C++ 26 via reflection which on that issue closes the gap with Rust's #[derive(Debug)].
- pjmlp 2y agoPerfectly iostreams happy user since 1993.
- codr7 2y agoSame, as long as I stay the hell away from locales/facets. Type safe input/output stream types and memory backed streams served on a silver plate is a pretty decent improvement over C.
- Dwedit 2y agoint a; cin >> a; Then the program goes berserk as soon as the first non-number is read out of standard input. All the other "cin >> integer" lines are immediately skipped. Yes, I know about error checking, clearing error condition, discarding characters. But it's a whole lot of stuff you need to do after every single "cin>>" line. It makes the simplicity of cin not worth it.
- tightbookkeeper 2y ago
- Someone 2y ago> C++ code can seamlessly add #include "sqlite3.h" unchanged. Almost seamlessly. You have to do extern “C” { #include "sqlite3.h" } (https://isocpp.org/wiki/faq/mixing-c-and-cpp#include-c-hdrs-nonsystem https://isocpp.org/wiki/faq/mixing-c-and-cpp#include-c-hdrs-...)
- deleted 2y ago[deleted]
- cornstalks 2y agoIf we're nitpicking then sqlite3.h already has `#ifdef __cplusplus` and `extern "C" {`. So yes, from the user's perspective it is seamless. They do not need to play the `extern "C" {` game.
- rramadass 2y agoYep; I think of it as "C/C++" and not "C" and/or "C++" i.e. one "multi-paradigm" language with different sets of mix-and-match.
- varjag 2y agokinda like python and ruby