Live data from Hacker News

Modernizing C arrays for greater memory safety: a case study in the Linux kernel

people.kernel.org

81–90 of 126 posts

Re: Modernizing C arrays for greater memory safety: a case study in the Linux kernel

#81

For code that is critical to performance, C99's "flexible array at the end of a struct" is an useful tool. It basically allows you to attach a header at the beginning of some dynamically-allocated binary data of infinite length (yes, it can be implemented as a pointer at the end of the struct, but the extra latency of another pointer chasing can reduce performance). Before C99, the "size-1 hack" or "size-0 GCC extens…

Because C++ has offered better alternatives for bounds checked data structures since it exists.

Re: Modernizing C arrays for greater memory safety: a case study in the Linux kernel

#82

For code that is critical to performance, C99's "flexible array at the end of a struct" is an useful tool. It basically allows you to attach a header at the beginning of some dynamically-allocated binary data of infinite length (yes, it can be implemented as a pointer at the end of the struct, but the extra latency of another pointer chasing can reduce performance). Before C99, the "size-1 hack" or "size-0 GCC extens…

No, C++ has nothing better.

here's a worse way that's a lot more work and maybe has some advantages:

https://gist.github.com/cozzyd/efda739301bb7eb3a4a63a145c93e...

Re: Modernizing C arrays for greater memory safety: a case study in the Linux kernel

#83
post #18

Good article. If you're compiling C with MSVC then you can use SAL annotations [1] which serve the same purpose. [1] https://learn.microsoft.com/en-us/cpp/code-quality/annotatin...

Wow, such a great annotation language. Wish it were in GCC as well.

Re: Modernizing C arrays for greater memory safety: a case study in the Linux kernel

#85

> int flex[] __attribute__((__element_count__(items))); While what the article describes is clever, it is needlessly complex, and filled with various compiler switches and extensions. In contrast, here's a stupid simple approach: https://www.digitalmars.com/articles/C-biggest-mistake.html where bounds-checkable arrays are declared as: int a[..]; `a` consists of two fields, a `length` and a `pointer`. Indexing it mean…

This isn't the same thing though. A flex array includes the data inline in the struct so allocating a struct with a flex array at the end requires just one call to malloc and avoids a pointer indirection when indexing into the array.

Re: Modernizing C arrays for greater memory safety: a case study in the Linux kernel

#86
post #27

Earlier quoted context omitted.

malloc() doesn't allocate arrays. It allocates blocks of memory. Hence sizeof doesn't work the same for malloc() objects as it does on arrays.

sizeof doesn't work the same for malloc() because the type of the returned value is a pointer, and the behavior of sizeof is dependent solely on the static type. For comparison, calloc() is specifically defined as "allocates space for an array of ... objects" in the Standard, but since return type is still void*, the caveat with sizeof still applies.

> sizeof is dependent solely on the static type

so what, an array has a size that sizeof can measure. what is returned from malloc is not an array and what sizeof measures is not reflective of the size of the allocation

Re: Modernizing C arrays for greater memory safety: a case study in the Linux kernel

#87
post #43

Earlier quoted context omitted.

Flexible array members are commonly supported as an extension in C++ compilers, but the C++ standard itself does not permit them. And FWIW `extern "C"` doesn't drop a C++ compiler into a "C mode", it merely effects linkage (i.e. name mangling); all the code within the scope must still be valid, compiler-supported C++. Your example code compiles the same without the extern "C" declaration. And it compiles the same if…

Unrelated to the article but since you seem to know this stuff, do you know what happens when a function in an “extern C” block exposes C++ types (parameters or return types)? I assume it’s broken because it’d expect the actual C++ types to be passed in despite the lack of ABI stability, and only the linking / name mangling is affected (possibly calling conventions as well?) but I’m not actually sure.

C++ types are structs and unions if you get down to the bottom of things. This is possibly not guaranteed by the standard, but AFAIK, extern "C" doesn’t ever affect the calling convention or memory layout for the parameters, only the name mangling for the linker. So in theory, if you manage to construct a valid std::string in C code (which is hard, given its invariants, and would be absolutely nonportable), then you could pass it to an extern "C" function that’s written in C++.

Re: Modernizing C arrays for greater memory safety: a case study in the Linux kernel

#88
post #27

Earlier quoted context omitted.

malloc() doesn't allocate arrays. It allocates blocks of memory. Hence sizeof doesn't work the same for malloc() objects as it does on arrays.

sizeof doesn't work the same for malloc() because the type of the returned value is a pointer, and the behavior of sizeof is dependent solely on the static type. For comparison, calloc() is specifically defined as "allocates space for an array of ... objects" in the Standard, but since return type is still void*, the caveat with sizeof still applies.

That is not true, as long as VLA:s are in the language spec for the version you're using.

This works:

    void vla_print(int n)
    {
      int foo[n];
      printf("Got %zu bytes right there!\n", sizeof foo);
    }

    int main(void)
    {
       vla_print(47);
       return 0;
    }
This prints 188 [1].

Even if you "hide" n from the compiler, i.e. make its value something that is only known at run-time (which is jumping through hoops, pretty sure the above is enough).

Also, it was jarring that the fine article kept referring to sizeof as sizeof(), a notation that C programmers typically use to identify function names. As everyone knows, sizeof is not a function. It's an operator. I really need to print up that t-shirt soon. Or maybe my first tattoo ... Hm.

[1]: https://ideone.com/kKf3bT

Re: Modernizing C arrays for greater memory safety: a case study in the Linux kernel

#90

Earlier quoted context omitted.

That's nice, but attributes let us easily retrofit existing C code such as the Linux kernel in a way that supports multiple compilers and compiler versions. Just extensions, not compiler switches. And they don't muck with the ABI which is a requirement for stable kernel driver interfaces. Also what you're proposing...would be an extension!

Starting with "That's nice" is extremely flippant and is an immediate turn off to any subsequent statement. A stronger opening to discredit the [..] proposal would be to take the closing quote "We've been doing that with D for over 20 years" and point out that storing the length of an array of a certain type is a specialization to arrays of dependent typing that has been around since Howard and de Bruijn extended lam…

Fat pointers are a purely value level construct. STLC alone covers that. Non-determinism isn't really related to the lambda cube, even CoC is deterministic.
Post reply on HN