Live data from Hacker News

Generic dynamic array in 60 lines of C

gist.github.com

61–70 of 110 posts

Re: Generic dynamic array in 60 lines of C

#61

I think this author should learn about the "do {} while(0)" trick.

What's the benefit of do {...} while (0) vs just {...} ?

You can put it inside a braceless if/else statement and follow it with a semicolon.

Compare:

  #define FOO() { ... }
  #define BAR() do { ... } while (0)
In the former case:

  if (x)
    FOO();
  else
    ...;
  
  // becomes
  if (x) {
    ...
  }
  ;
  else
    ...;
In the latter case:

  if (x)
    BAR();
  else
    ...;
  
  // becomes
  if (x)
    do {
      ...
    } while (0);
  else
    ...;

Re: Generic dynamic array in 60 lines of C

#62

Earlier quoted context omitted.

What's the benefit of do {...} while (0) vs just {...} ?

Works if you want to e.g. skip braces if if..else... statements. Some would say putting braces in always is good style, but I like skipping them myself so won't defend it :)

I agree it’s good style, but surrounding code using bad style is still poor excuse for writing macros which break.

Re: Generic dynamic array in 60 lines of C

#64
post #60

Earlier quoted context omitted.

What's the benefit of do {...} while (0) vs just {...} ?

do {…} while (0) is a statement, so it can be put between “if (…)” and “; else”, while just {…} would result in a syntax error due to a hanging else.

OK, but I guess what's really being relied on there is that it's syntactically still a single statement when you follow it with ';', whereas {...}; is two statements (which is what breaks the if-else).

I just discovered that gcc also supports non-standard "statement expressions" of the form ({...}) which would serve the same purpose at the cost of portability.

Re: Generic dynamic array in 60 lines of C

#65

Heavy use of macros to do metaprogramming is a strong sign it's time to move to a more powerful language.

I don't have this luxury if I want to learn about ffmpeg libraries, its all written in c, almost all media and hardware accelerator libraries are written in c, you go to another language they just bind to c. its soo frustrating but I've no choice but to stick with c.

D code can call C functions directly.

Re: Generic dynamic array in 60 lines of C

#66
post #46

Earlier quoted context omitted.

Where do you check that capacity is nonzero? When capacity is zero, what happens on this line? a.capacity "all c code is unsafe" is not an excuse to permit bloody obvious, undocumented memory overruns. I write a lot of c. Avoiding the unsafe bits, avoiding UB, is the skill required to write good c. "C code is unsafe" is a Rustacean marketing slogan. Don't believe it, but definitely don't practice it.

just don't initialize it with 0 capacity :-)

Why not just fix it? It's a trivial fix and has the added benefit that a zero-initialized DYN_ARR_OF(x) struct would be in a valid state, which is always nice. A struct with several dynamic arrays can then much simpler to initialize, for example.

Re: Generic dynamic array in 60 lines of C

#67

Earlier quoted context omitted.

Also a far worse language though. Macros have their place, but trying to do anything complex with them just turns into a total nightmare. They're hard to reason about, walk through, or modify. If heavy macro usage is found, it's definitely time to reconsider the approach.

It really depends on how macros are used. If you're just using them to implement "high level language features", it's not a problem; sure, you might have trouble figuring out what STAILQ_INSERT_TAIL does internally, but you're going to have just as much trouble figuring out what the Lisp or Perl or Python "add this item to the end of that list" operations do internally. Macros can be a nightmare, but when they're use…

> when they're used properly they're not

Yeah, they are.

Source: Decades of C programming

Re: Generic dynamic array in 60 lines of C

#68
post #39

DON'T USE THIS As fpoling points out, capacity is a 32-bit unsigned. That can overflow. There is no safety in append: if capacity is zero no new space will be made, if capacity overflows the realloc will not have enough space -- in either case, you end up writing past the end. Allocating a [capacity] zero array and appending to it is extremely common. That you'll write past the end in that case shows that the author…

Is this overflow really a realistic scenario? I imagine most machines won't even permit you to allocate the sorts of sizes that would cause this bug. In that scenario (where you're allocating a multi-gigabytes array), you typically know the size ahead of time, instead of growing it dynamically, as the latter doesn't really perform too well.

2Gb (1really easy to blow that limit. And what's the point of this dynamically-growing array if not to forget about managing capacity?

Re: Generic dynamic array in 60 lines of C

#69
I don't like the use of macros for things like this. Macros in general should rarely or sparingly be used.

I'm also not certain one should use "end pointers." Conventionally, it seems more advisable to use `size_t capacity`, `size_t length`, and `void *data`.

Great use of Cunningham's Law, though! I appreciate C posts on Hacker News.

Post reply on HN