gcjr:
didn't Scott Meyers write Effective C++ discussing the pitfalls of using new() and delete()?
Yes, and he's absolutely right. You shouldn't be manually allocating stuff in C++, always prefer the standard containers (such as std::vector
) and smart pointers with std::make_unique
or std::make_shared
. That eliminates any possible memory leaks altogether, and results in clearer code.
That being said, new and delete do have their place in the C++ language, it's what's used under the hood to implement std::vector and smart pointers, and they can be used for writing custom data structures and containers.
Malloc and free, on the other hand, have no place in C++, they should only be used in C. Using malloc in C++ doesn't call the constructor, and will most likely result in undefined behavior. C++ has a strict notion of object lifetime (it has constructors and deterministic destruction).
If you allocate storage for an object using malloc, it does just that: allocate memory. As far as C++ is concerned, it's just raw memory, not an object.
gcjr:
i'm curious about a good practice in C that is not a good practice in C++.
C programmers tend to use macros for a lot of things, such as constants, small inline functions. This leads to type errors, and unexpected behavior, such as the abs
macro defined by the Arduino Core:
Notes and Warnings
Because of the way the abs() function is implemented, avoid using other functions inside the brackets, it may lead to incorrect results.
abs(a++); // avoid this - yields incorrect results
// use this instead:
abs(a);
a++; // keep other math outside the function
It's much safer and more appropriate to use const or constexpr variables and functions in C++. Constexpr functions are evaluated at compile-time, and can be used in constant contexts such as array sizes, so there's really no reason to use macros instead.
Type punning using unions is fine in C, but invokes undefined behavior (and bad type safety) in C++.
C programmers are used to manually allocating memory in C, and manually initializing or cleaning up resources. C++ has smart pointers, as mentioned earlier, constructors for initialization, and patterns like RAII to handle cleanup. This eliminates any possible resource leaks.
In C, casting pointers to data and even functions to (void *) is common practice, especially when dealing with APIs that provide callbacks or communication libraries such as MPI. C++ has templates, lambda functions, and type-safe std::variant, std::any and std::function types for these purposes.
Some C programmers have some very stubborn misconceptions when it comes to performance, and refuse to use OOP or exceptions because of a possible performance hit, even when that's demonstrably false.
Don't get me wrong, some people abuse OOP for huge unrelated inheritance structures, but the pattern is very useful in many cases, and calling a method on an object in C++ is just as fast as passing a pointer to a free function in C.
There is a small performance hit if you use virtual functions (which you have to declare explicitly), but even then, it's faster or equally fast as the alternatives. Most importantly: it'll be much more readable than the procedural equivalent.
This list is getting long enough, I'll end my rant here 
Just to be absolutely clear: I'm not blaming any C programmers, and most of the things I mentioned are perfectly fine in a C code base. But old habits die hard, so some C programmers also apply the same techniques to C++ code where it's not appropriate.
gcjr:
some would say about C++ "It does a lot of things half well and it's just a garbage heap of ideas that are mutually exclusive." and develop their own language, Go
Well, Ken Thompson might be a bit biased in the C vs C++ debate 
He did have a point though, especially back in 2009. There were times where C++ lacked a clear vision, but I don't think that's the case anymore since C++11 and more recent releases, although it still caries some of that earlier baggage in the name of backwards compatibility. This results in some alternative ways of achieving the same thing, which can be confusing. Large effort is being done in standardizing this, though, such as the C++ Core Guidelines.
gcjr:
i believe learning good programming techniques will help in any language
Absolutely, but not all concepts can be applied in the same way in all languages.