You move it to C/C++ (after not being able to speed up the python code using FFI or something else).
Do you go C or C++?
Even if I'm writing C++, I find myself using a restricted subset that is mostly C.
You move it to C/C++ (after not being able to speed up the python code using FFI or something else).
Do you go C or C++?
Even if I'm writing C++, I find myself using a restricted subset that is mostly C.
If you don't need classes, maybe you should look into Rust - it's quite a bit more restrictive, but it allows a nice, functional style with similar performance while avoiding most of the pitfalls and footguns of C.
It's a coding pattern that has its specific use, but that's definitely not something that's missing from C or a natural extension to how things are generally done in it.
As far as I understand, smart pointers are actually a somewhat stupid form of garbage collection.
People who complain about C++ smart pointers tend to be the ones who reflexively reach for shared_ptr. (We call that habit "Java Disease".) Most good C++ programs have zero uses of shared_ptr. Also, passing around shared_ptr or unique_ptr in public interfaces puts you in a state of sin.
Why is that?
In practice, the new type usually starts out as a PIMPL class with just a std::unique_ptr<impl> member. But often, once the type is named, you discover it is a good place to park more operations.
There are many features of C++ that would make a "better C", like namespaces and templates (which are better macros). But as good as they are in other contexts, smart-pointers are the last thing I want in C-like code.
Also, an advantage of C over C++ is that it doesn't have a runtime and it doesn't use name mangling. That makes linking much easier and particularly well suited to embedded applications.
If you have a program in "mostly C", you can start using RAII to manage your ressources. Then use std::unique_ptr, std::shared_ptr, and references instead of raw pointers. And namespaces. That already brings you to a very nice place without shifting completely to modern C++.
You don't have to use all the features of C++ if you don't need them.
Then the thing grows to a team of 20, and you find yourself applying restrictive rules about which subset of C++ is admissible, because otherwise everyone will consider a different subset for their own code.
"You don't need to use all of the language" is a false claim that doesn't go too far without adding extra friction to the project management.
extern "C" {
// my C++ code
}
Big deal.By the way, clang and Visual C runtime libraries are actually implemented in C++ with extern "C".
if I was using C++ to write business applications or something, like one would use C# or Java or whatever, then yeah, smart pointers seem like they would be useful in that specific domain... but at that point, why not just use one of those languages, or a language like it?
I'm probably going to try zig for my next endeavor into lower-level game development because that language, while different from the C-style-C++ I'm used to, seems much more in line with the kind of programming I'm looking to do, compared to modern C++. I don't want RAII, smart pointers, and all that conceptual overhead jazz. I want to allocate memory, run operations on said memory, then free said memory. I kinda miss just doing stuff in C89.
Resource deallocation becomes extremely difficult in the context of (various types of) exception handling. C++ destructors make this a breeze.
like I said, this mindset might be domain-specific, I'm not sure, I haven't used C++ meaningfully for anything else.
There's basically no resource overhead for using the pointer abstractions that C++ offers.
Recall that the original comment was discussing whether to re-write something originally written in Python into C or C++.
std::unique_ptr & std::shared_ptr are amazing. If you're still writing new & delete, you're just making things harder on yourself. I'll still use raw pointers in C++, but only the a borrowing context. It massively simplifies ownership. No more reading docs to try and guess if this pointer being passed in or returned needs to be freed or not. If I own it, it's a unique_ptr. If I'm giving it to someone else, it's a unique_ptr&&. If I'm letting something borrow it, it's a raw pointer or reference.
Or I'll make my own smart pointer containers for allocations with special lifecycles, like per-frame allocations from a custom arena allocation that must not be destroyed with delete/free.
Why try to remember all your lifecycle manually, which is incredibly error prone and no you're not immune to mistakes here, when you can compiler-enforce it instead?
It also needlessly prevents the function from working in both shared_ptr & unique_ptr contexts.
Same thing for plain old references, although I tend to stick to pointers if the function is mutating as it makes that clearer at the callsite.
void ptr_add(int *f) {
*f += 5;
}
void val_add(int f) {
f += 5; // only changes local copy of f
}
void ref_add(int &f) {
f += 5;
}
int main() {
int foo = 42;
ptr_add(&foo); // foo is now 47
val_add(foo); // foo is still 47
ref_add(foo); // foo is now 52
}Your expertise is laudable and am sure, hard won. The trouble is with expecting a larger team to buy into that philosophy.
I didn't say "always use references", I said, never use raw pointers. Since shared_ptrs can be null, I don't see why this is a valid counterargument.
Pragmatism beats dogmatism in practice.
No problem, but also little to no benefit. Why get in the habit of using them when you don't have to?
But these days I may prefer Rust over the two instead, if it’s not a numeric-heavy program.
* auto
* namespaces
* templates
* lambdas
The standard library is much more useful and expansive than C's.
And if you really care about performance, C++ is the obvious choice (but it does have its pitfalls, I think).