Live data from Hacker News

Emulating Swift's “defer” in C, with Clang or GCC+Blocks

fdiv.net

11–20 of 33 posts

Re: Emulating Swift's “defer” in C, with Clang or GCC+Blocks

#11
post #9

[deleted]

A std::vector per defer? Copying rather than moving std::funcs? Inserting into front of vector of funcs? Gratuitous allocs galore!

Just give me a wrapper with a destructor plz. (uniq_ptr can even get the job done in a pinch)

Re: Emulating Swift's “defer” in C, with Clang or GCC+Blocks

#13
post #12

Earlier quoted context omitted.

A std::vector per defer? Copying rather than moving std::funcs? Inserting into front of vector of funcs? Gratuitous allocs galore! Just give me a wrapper with a destructor plz. (uniq_ptr can even get the job done in a pinch)

[deleted]

See rarely used second template arg of unique_ptr- the cleanup fn can be specified.

Re: Emulating Swift's “defer” in C, with Clang or GCC+Blocks

#14
post #8

The canonical method in C is to jump to a named label which hosts some functions to unwind/close any open descriptors or operations. As it involves the use of a goto statement, it drives certain people mad. I wasn't aware of C Blocks.

Clang's blocks produce atrocious code. Look at the disassembly for: int main(){ __block int (^foo)(int x) = ^ int (int x) { if(x versus the GCC: int main(){ int foo(int x) { if(x if you want to see what I'm talking about. CLANG: http://pastebin.com/37A9by4V GCC: http://pastebin.com/RMEDnwxi However, defer does look interesting, and implementing it for GCC is very easy: #define defer_(x) do{}while(0); \ auto void _dto…

What purpose does the empty do{}while(0); statement serve here?

Re: Emulating Swift's “defer” in C, with Clang or GCC+Blocks

#15
post #14
post #8

Earlier quoted context omitted.

Clang's blocks produce atrocious code. Look at the disassembly for: int main(){ __block int (^foo)(int x) = ^ int (int x) { if(x versus the GCC: int main(){ int foo(int x) { if(x if you want to see what I'm talking about. CLANG: http://pastebin.com/37A9by4V GCC: http://pastebin.com/RMEDnwxi However, defer does look interesting, and implementing it for GCC is very easy: #define defer_(x) do{}while(0); \ auto void _dto…

What purpose does the empty do{}while(0); statement serve here?

It puts the whole #define code into a single expression so you can do

  if (cond)
    MACRO;
and the macro won't expand incorrectly to

  if (cond)
    foo;
  bar;
I personally just go the anal retentive route and use brackets everywhere.

Re: Emulating Swift's “defer” in C, with Clang or GCC+Blocks

#16
post #14
post #8

Earlier quoted context omitted.

Clang's blocks produce atrocious code. Look at the disassembly for: int main(){ __block int (^foo)(int x) = ^ int (int x) { if(x versus the GCC: int main(){ int foo(int x) { if(x if you want to see what I'm talking about. CLANG: http://pastebin.com/37A9by4V GCC: http://pastebin.com/RMEDnwxi However, defer does look interesting, and implementing it for GCC is very easy: #define defer_(x) do{}while(0); \ auto void _dto…

What purpose does the empty do{}while(0); statement serve here?

No syntax error if someone writes if(x)defer. Probably better to have a big error message since we can't curry the if.

if(x){defer} will be wrong, but it'll be wrong in a different way.

Re: Emulating Swift's “defer” in C, with Clang or GCC+Blocks

#18
post #4

Not the same semantics, as least compared to Golang. This is block-scoped, but "defer" in Go is function-scoped and has highly dynamic semantics—for example, call it in a loop and the compiler may not be able to statically prove how many times it will run. (Note that, IMO, the semantics of the feature as implemented in the article are preferable to those of Golang, so I wouldn't personally go to the effort of trying…

Unless I'm mistaken, `__attribute__((cleanup))` is function-, not block-, scoped. The cleanup attribute is actually declared on the Block, which is kind of cute.

Instead, I'd suggest just making regular use of `__attribute__((cleanup))` in C under GCC or Clang and avoiding C blocks entirely. In this case you could do something like:

  #define AUTOCLOSE_FILE(n) __attribute__((cleanup(autoclose_file))) n = NULL
  
  void
  autoclose_file(FILE *f)
  {
    if (f)
      fclose(f);
  }
  
  int
  main(...)
  {
    FILE AUTOCLOSE_FILE(*a), AUTOCLOSE_FILE(*b);
  
    a = fopen("foo");
    if (!a)
      return;

    b = fopen("bar");
    if (!b)
      return;
  
    ...
  }

Re: Emulating Swift's “defer” in C, with Clang or GCC+Blocks

#19
post #15
post #14

Earlier quoted context omitted.

What purpose does the empty do{}while(0); statement serve here?

It puts the whole #define code into a single expression so you can do if (cond) MACRO; and the macro won't expand incorrectly to if (cond) foo; bar; I personally just go the anal retentive route and use brackets everywhere.

Not in this case it doesn't.

Re: Emulating Swift's “defer” in C, with Clang or GCC+Blocks

#20
post #8

The canonical method in C is to jump to a named label which hosts some functions to unwind/close any open descriptors or operations. As it involves the use of a goto statement, it drives certain people mad. I wasn't aware of C Blocks.

Clang's blocks produce atrocious code. Look at the disassembly for: int main(){ __block int (^foo)(int x) = ^ int (int x) { if(x versus the GCC: int main(){ int foo(int x) { if(x if you want to see what I'm talking about. CLANG: http://pastebin.com/37A9by4V GCC: http://pastebin.com/RMEDnwxi However, defer does look interesting, and implementing it for GCC is very easy: #define defer_(x) do{}while(0); \ auto void _dto…

That's pretty cute.
Post reply on HN