4 ms·
It’s pedantic, but in the malloc example, I’d put the defer immediately after the assignment. This makes it very obvious that the defer/free goes along with the
by jonhohle 8mo ago
It’s pedantic, but in the malloc example, I’d put the defer immediately after the assignment. This makes it very obvious that the defer/free goes along with the allocation.
It would run regardless of if malloc succeeded or failed, but calling free on a NULL pointer is safe (defined to no-op in the C-spec).
- deleted 8mo ago[deleted]
- flakes 8mo agoI'd say a lot of users are going to borrow patterns from Go, where you'd typically check the error first. resource, err := newResource() if err != nil { return err } defer resource.Close() IMO this pattern makes more sense, as calling exit behavior in most cases won't make sense unless you have acquired the resource in the first place. free may accept a NULL pointer, but it also doesn't need to be called with one either.
- maccard 8mo agoThis example is exactly why RAII is the solution to this problem and not defer.
- miguel_martin 8mo agodefer is literally just an explicit RAII in this example. That is, it's just unnecessary boiler plate to wrap the newResource handle into a struct in this context. In addition, RAII has it's own complexities that need to be dealt with now, i.e. move semantics, which obviously C does not have nor will it likely ever.
- maccard 8mo ago> RAII has it's own complexities that need to be dealt with now, i.e. move semantics, which obviously C does not have nor will it likely ever. In the example above, the question of "do I put defer before or after the `if err != nil` check" is deferred to the programmer. RAII forces you to handle the complexity, defer lets you shoot yourself in the foot.
- mort96 8mo agoI love RAII. C++ and Rust are my favourite languages for a lot of things thanks to RAII. RAII is not the right solution for C. I wouldn't want C to grow constructors and destructors. So far, C only runs the code you ask it to; turning variable declaration into a hidden magic constructor call would, IMO, fly in the face of why people may choose C in the first place.
- masklinn 8mo agoIt seems less pedantic and more unnecessarily dangerous due to its non uniformity: in the general case the resource won’t exist on error, and breaking the pattern for malloc adds inconsistency without any actual value gain.
- krautsauer 8mo ago3…2…1… and somebody writes a malloc macro that includes the defer.
- mort96 8mo agoFree works with NULL, but not all cleanup functions do. Instead of deciding whether to defer before or after the null check on a case-by-case basis based on whether the cleanup function handles NULL gracefully, I would just always do the defer after the null check regardless of which pair of allocation/cleanup functions I use.