Live data from Hacker News

I write type-safe generic data structures in C

danielchasehooper.com

121–130 of 196 posts

Re: I write type-safe generic data structures in C

#121

Earlier quoted context omitted.

You could take away anything you use and say "but we could make it ourselves", that doesn't mean it's helpful.

Except it’s very common for C programs to contain one-off data structures, so it’s not a hypothetical. It’s a concrete programming style.

Do you mean a data structure they only use once? Or one that's never been done elsewhere? If they only use it once, that seems like the worst effort/pay-off ratio you can get writing it yourself. And I don't think there's that many fundamental data structures out there... and even then, why would it be good to be forced to make your bespoke structure out of only arrays, when things like maps exist?

Re: I write type-safe generic data structures in C

#122
post #20
post #12

For your level 2 code, `uint64_t data[];` is wrong for types whose alignment is greater than `uint64_t`, and also wasteful for types whose alignment is smaller (for example, under an ilp32 ABI on 64-bit architectures). For your level 3 code, it should be `int main() { List(Foo) foo_list = {NULL};` Note that working around a lack of `typeof` means you can't return anything. Also, your particular workaround allows `con…

I would love for `union`s to be federated, that is, a type could declare itself as thought it was part of a union with another type, without having to pre-declare all possible types in one place.

Can't you just declare anonymous unions whenever? E.g.

    struct foo { ... };
    
    struct bar { ... };

    struct bar check_this_out(struct foo foo) {
        return ((union { struct foo foo; struct bar bar; }){ .foo = foo}).bar;
    }

    struct bar *also_this(struct foo *foo) {
        union { struct foo foo; struct bar bar; } *tmp = (void*)foo;
        return &tmp->bar;
    }

Re: I write type-safe generic data structures in C

#124
post #33
post #22

The casting of the function type assumes that the item pointer type (e.g. Foo*) has the same representation as void*, which the C standard doesn’t guarantee (in standardese: the two types aren’t “compatible”). Calling the function with the converted type therefore constitutes undefined behavior. It also impacts aliasing analysis by compilers (see [0], incidentally), even if the pointer representation happens to be th…

This is addressed in the footnotes. casting is not the core of the type safety. Read the whole article.

Working with function pointers is always finicky. I once had MSVC fold together

    int f0(int x) { return x; }

    int f1(int x, int y) { return y; }
into a single function, so at runtime, (void(*)())f0 and (void(*)())f1 would compare equal. AFAIK, you are not guaranteed by the standard that functions of different signatures would, when their addresses are taken, result in different pointers, so it's not technically a bug... but it's quite surprising, and ruins certain tricks.

Re: I write type-safe generic data structures in C

#125
post #28

There's also the method used in the Linux kernel to embed the list information (struct list_head) within the type specific struct. https://kernelnewbies.org/FAQ/LinkedLists

The naming of LIST_HEAD_INIT and INIT_LIST_HEAD is confusing to me.

Not to mention that they insist on calling every entry of the list a "list head", which makes no sense (hysterical raisins, maybe?). The structure is made of a uniform loop of entries, one of which is used as the actual head & tail, or entry point into the structure.

Re: I write type-safe generic data structures in C

#126

Earlier quoted context omitted.

The naming of LIST_HEAD_INIT and INIT_LIST_HEAD is confusing to me.

Not to mention that they insist on calling every entry of the list a "list head", which makes no sense (hysterical raisins, maybe?). The structure is made of a uniform loop of entries, one of which is used as the actual head & tail, or entry point into the structure.

Yes, it's terrible, and the fact that their list_add takes parameters backwards from what one might expect, with no types to catch mistakes!

See https://github.com/rustyrussell/ccan/blob/master/ccan/list/_...

Re: I write type-safe generic data structures in C

#127

Earlier quoted context omitted.

Not to mention that they insist on calling every entry of the list a "list head", which makes no sense (hysterical raisins, maybe?). The structure is made of a uniform loop of entries, one of which is used as the actual head & tail, or entry point into the structure.

Yes, it's terrible, and the fact that their list_add takes parameters backwards from what one might expect, with no types to catch mistakes! See https://github.com/rustyrussell/ccan/blob/master/ccan/list/_...

Absolutely. Wrapping the distinguished entry point in a new structure type equipped with a thin type-safe wrapper API that covers the most common use case is the way to go.

Re: I write type-safe generic data structures in C

#128
post #118

Earlier quoted context omitted.

This is incorrect. In a function definition, an empty list means it takes no parameters. 6.7.5.3 Function declarators > 14. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters.

"has no parameters" is not the same as "cannot take arguments". Defining `int main()` does not stop the runtime from passing the usual 3 arguments (typically named argc, argv, envp), it only means that no parameters are bound to those arguments. Technically it's no problem to have a C function ignore its arguments by not binding parameters. Way too many programmers seem to not understand the difference between parame…

Surely part of the problem is having a distinct term and handling for parameters passed to functions. What is the point? It seems confusing with no upside.

Re: I write type-safe generic data structures in C

#129

Earlier quoted context omitted.

Unless it is a popular system or common architecture, yes.

Could you show me an example of a micro controller still supported today which doesn't have a C++ compiler?

The 8051. I think C++ compilers technically exist for it, but for most hardware the only practical choice is the Keil C51 compiler, which is C89.
Post reply on HN