Live data from Hacker News

The Defer Technical Specification: It Is Time

thephd.dev

11–20 of 77 posts

Re: The Defer Technical Specification: It Is Time

#11

What is the recommended way to use defer to free values only on an error path (rather than all paths)? Currently I use goto for this: void* p1 = malloc(...); if (!p1) goto err1; void* p2 = malloc(...); if (!p2) goto err2; void* p3 = malloc(...); if (!p3) goto err3; return {p1, p2, p3}; err3: free(p2); err2: free(p1); err1: return NULL; With defer I think I would have to use a "success" boolean like this: bool success…

I don't even bother with `error1`, `error2`, ... `errorN`.

I initialise all pointers to NULL at the top of the function and use `goto cleanup`, which cleans up everything that is not being returned ... because `free(some_ptr)` where `some_ptr` is NULL is perfectly legal.

Re: The Defer Technical Specification: It Is Time

#12

What is the recommended way to use defer to free values only on an error path (rather than all paths)? Currently I use goto for this: void* p1 = malloc(...); if (!p1) goto err1; void* p2 = malloc(...); if (!p2) goto err2; void* p3 = malloc(...); if (!p3) goto err3; return {p1, p2, p3}; err3: free(p2); err2: free(p1); err1: return NULL; With defer I think I would have to use a "success" boolean like this: bool success…

That is a well structure system, yes Both cleanup for error and allocation happens in the same place

That means you won't forget to call it, and the success flag is an obvious way to ha dle it

Re: The Defer Technical Specification: It Is Time

#14
post #3

I've been doing properly scoped defers in C since forever, as long as you have access to cleanup attributes and nested functions it's no big deal. https://github.com/codr7/hacktical-c/tree/main/macro

Yes, the proposal is tailored so that other than simple syntax support no new semantics need to be implemented within GCC to support defer, though clang will need to finally add support for nested functions--in spirit if not the literal GCC extension.[1] The proposal also gives consideration to MSVC's try/finally to minimize the amount of effort required there to support defer.

[1] Because defer takes a block, not a simple statement. And deferred blocks can be defined recursively--i.e. defer within a defer block.

Re: The Defer Technical Specification: It Is Time

#16

What is the recommended way to use defer to free values only on an error path (rather than all paths)? Currently I use goto for this: void* p1 = malloc(...); if (!p1) goto err1; void* p2 = malloc(...); if (!p2) goto err2; void* p3 = malloc(...); if (!p3) goto err3; return {p1, p2, p3}; err3: free(p2); err2: free(p1); err1: return NULL; With defer I think I would have to use a "success" boolean like this: bool success…

[deleted]

Re: The Defer Technical Specification: It Is Time

#17

What is the recommended way to use defer to free values only on an error path (rather than all paths)? Currently I use goto for this: void* p1 = malloc(...); if (!p1) goto err1; void* p2 = malloc(...); if (!p2) goto err2; void* p3 = malloc(...); if (!p3) goto err3; return {p1, p2, p3}; err3: free(p2); err2: free(p1); err1: return NULL; With defer I think I would have to use a "success" boolean like this: bool success…

Can also use a different variable name for the success case and null out any successfully consumed temporaries.

    void* p1 = malloc();
    if (!p1) return failure;
    defer { free(p1); }
    ...
    someOther->pointer = p1;
    p1 = NULL;
    return success;

Re: The Defer Technical Specification: It Is Time

#19

What is the recommended way to use defer to free values only on an error path (rather than all paths)? Currently I use goto for this: void* p1 = malloc(...); if (!p1) goto err1; void* p2 = malloc(...); if (!p2) goto err2; void* p3 = malloc(...); if (!p3) goto err3; return {p1, p2, p3}; err3: free(p2); err2: free(p1); err1: return NULL; With defer I think I would have to use a "success" boolean like this: bool success…

I'm not sure I'd do either for this trivial case, but it might make sense where the cleanup logic is more complex?

    void* p1 = malloc(...);
    void* p2 = malloc(...);
    void* p3 = malloc(...);

    if(p1 && p2 && p3)
      return {p1, p2, p3};

    free(p3);
    free(p2);
    free(p1);
    return NULL;
Post reply on HN