7 ms·
This reminded me of another C syntax strangeness: "Flexible array member". It allows you to do something like this: struct items_with_header { int header_f
by skarap 11y ago
This reminded me of another C syntax strangeness: "Flexible array member". It allows you to do something like this:
struct items_with_header {
int header_field1;
unsigned int length;
double array[];
};
Then allocate enough memory and use the struct to access it.
Used it once in a hash-table implementation.
- sepeth 11y agoI also used this in a similar situation, it helped me to save a lot of memory in my skiplist implementation: https://github.com/sepeth/python-skiplist/commit/00ae7f942467b3e78c6cce5d08ccbad20b520023 https://github.com/sepeth/python-skiplist/commit/00ae7f94246... Redis's skiplist is also using the same feature: https://github.com/antirez/redis/blob/unstable/src/server.h#L611 https://github.com/antirez/redis/blob/unstable/src/server.h#...
- skarap 11y agoIn my case the software used mmap-ed file for storage - I couldn't believe how easy is was to work with the data this way!
- brandmeyer 11y agoThis might be my biggest gripe with C's syntax. typename identifier[]; means three different things, depending on where it appears: As a function argument, it is a pointer that will be accessed like an array. As a variable with automatic storage duration, it is an array whose size will be determined by the right-hand-side of an assignment from a braced initializer list. In the middle of a struct definition, it's illegal. And at the end of a struct definition, it is a flexible array member.
- seba_dos1 11y agoMy favorite is similar thing, but in C++ and much more confusing: class Bar {}; class Foo { public: Foo(const Bar &c) { } void method() { } }; int main() { Foo foo(Bar()); foo.method(); return 0; } "foo.method();" doesn't compile because: error: request for member ‘method’ in ‘foo’, which is of non-class type ‘Foo(Bar (*)())’ That's right: "foo" is a declared function that returns instance of Foo and takes one argument - a function that returns instance of Bar :) But when you add additional parentheses in a line above: Foo foo((Bar())); then "foo" is an instance of Foo created by passing a new instance of Bar to its constructor, which is more like what you'd expect by reading the code, and the code compiles. Fun!
- BudVVeezer 11y agoYes, the most vexing parse. https://en.wikipedia.org/wiki/Most_vexing_parse https://en.wikipedia.org/wiki/Most_vexing_parse
- tylorr 11y agoI believe this situation is usually referred to as the "Most vexing parse".
- bobbyi_settv 11y agoC++11 initialization syntax solves this https://en.wikipedia.org/wiki/Most_vexing_parse#Uniform_initialization_syntax https://en.wikipedia.org/wiki/Most_vexing_parse#Uniform_init...
- Peaker 11y agoAs an extern'd variable it's an array of unknown length
- asveikau 11y agoAFAIK this this was only made legal by c99. Though I have seen it in code that is much older. (Pre-c99 you would give the "flexible" member an element size inside the square brackets, such as 0 or 1, but allocate as if it were a larger size on the heap.)