I am not convinced by this argument TBH. The one use case they come up with is testing APIs exposed through the FFI. APIs that need to be written in such a way as to avoid RAII as C does not support that. Their use case is testing and that is the only use case I can see that makes this valid - but TBH I don’t really see the value of adding defer as a language feature for testing FFI APIs. Any leaked data will be cleaned up at the end of the test suite and I would never use such APIs in production rust code without wrapping them in a RAII abstraction. Any other uses of such an API I would expect to happen in other languages where a rust defer feature wont help at all.
I am not a huge fan of the defer feature overall. It is error prone and easy to forget to use. With RAII the compiler deals with all that so you don’t have to. I have seen far too many memory leaks in prod in go where someone has forgotten a defer foo.Close() and it is not obvious at all when they have done that. Even flagged a few times where it looked like it was needed (like with things that are constructed with a Open(...) but that didn’t have a Close method… It just makes code reviews harder than when you can rely on RAII IMO.
This feels like wanting a feature to code in a non-rust style for those not used to the language which I really don’t want to encourage.
Hmm, ok… So I guess the only way to not trigger Undefined Behavior on the C side when freeing, would be to keep the capacity of the Vec around and do:
if (capacity > 0) {
free(foos);
}
Let’s ignore for now that this will surprise every C developer out there that have been doing if (NULL != ptr) free(ptr) for 50 years now.
That is not the only way, you can in the rust code return a null pointer when the Vecs capacity in 0 which will give you the behavior C developers are used to.
And I think generally their problem with needing to keep track of cap and length is due to Vec not being equivalent to a C array. If you want a C array then use a array or boxed slice instead of a Vec. The big problem here is not that C developers are not used to caring about capacity - but that they are not used to having to care about the difference between length and capacity. Instead the just call capacity ‘length’ and allocated/deallocate based on that. So the ‘length’ in a Vec is not the ‘length’ they typically deal with.
I am not convinced by this argument TBH. The one use case they come up with is testing APIs exposed through the FFI. APIs that need to be written in such a way as to avoid RAII as C does not support that. Their use case is testing and that is the only use case I can see that makes this valid - but TBH I don’t really see the value of adding defer as a language feature for testing FFI APIs. Any leaked data will be cleaned up at the end of the test suite and I would never use such APIs in production rust code without wrapping them in a RAII abstraction. Any other uses of such an API I would expect to happen in other languages where a rust defer feature wont help at all.
I am not a huge fan of the defer feature overall. It is error prone and easy to forget to use. With RAII the compiler deals with all that so you don’t have to. I have seen far too many memory leaks in prod in go where someone has forgotten a
defer foo.Close()
and it is not obvious at all when they have done that. Even flagged a few times where it looked like it was needed (like with things that are constructed with aOpen(...)
but that didn’t have a Close method… It just makes code reviews harder than when you can rely on RAII IMO.This feels like wanting a feature to code in a non-rust style for those not used to the language which I really don’t want to encourage.
That is not the only way, you can in the rust code return a null pointer when the Vecs capacity in 0 which will give you the behavior C developers are used to.
And I think generally their problem with needing to keep track of cap and length is due to Vec not being equivalent to a C array. If you want a C array then use a array or boxed slice instead of a Vec. The big problem here is not that C developers are not used to caring about capacity - but that they are not used to having to care about the difference between length and capacity. Instead the just call capacity ‘length’ and allocated/deallocate based on that. So the ‘length’ in a Vec is not the ‘length’ they typically deal with.