19 ms·
> no array bounds checking is possible. This isn’t strictly true, a C implementation is allowed to associate memory-range (or more generally, pointer provenanc
by layer8 2y ago
> no array bounds checking is possible.
This isn’t strictly true, a C implementation is allowed to associate memory-range (or more generally, pointer provenance) metadata with a pointer.
The DeathStation 9000 features a conforming C implementation which is known to catch all array bounds violations. ;)
- uecker 2y agoRight. Also it might it sound like array-to-pointer decay is forced onto the programmer. Instead, you can take the address of an array just fine without letting it decay. The type then preserves the length.
- codr7 2y agoNice, when you know the length at compile time, which is rarely from my experience. The holy grail is runtime access to the length, which means an array would have to be backed by something more elaborate.
- WalterBright 2y agoC: int foo(int a[]) { return a[5]; } int main() { int a[3]; return foo(a); } > gcc test.c > ./a.out Oops. D: int foo(int[] a) { return a[5]; } int main() { int[3] a; return foo(a); } > ./cc array.d > ./array core.exception.ArrayIndexError@array.d(1): index [5] is out of bounds for array of length 3 Ah, Nirvana! How to fix it for C: https://www.digitalmars.com/articles/C-biggest-mistake.html https://www.digitalmars.com/articles/C-biggest-mistake.html
- uecker 2y agoYou need to take the address of the array instead of letting it decay and then size is encoded in the type: int foo(int (*a)[6]) { return a[5]; } int main() { int a[3]; return foo(&a); } Or for run-time length: int foo(int n, int (*a)[n]) { return (\*a)[5]; } int main() { int a[3]; return foo(ARRAY_SIZE(a), &a); } /app/example.c:4:38: runtime error: index 5 out of bounds for type 'int[n]' https://godbolt.org/z/dxx7TsKbK\ https://godbolt.org/z/dxx7TsKbK\*
- marcodiego 2y ago\* what operator is this? I have never seen it. Where can I read about it?
- aw1621107 2y agoMy guess is that it was intended to escape the * since unescaped * in regular text on HN results in italics. Since the text in question is in a code block, though, that escaping is not needed.
- WalterBright 2y agoint foo(int n, int (*a)[n]) { return (\*a)[5]; } int main() { int a[3]; return foo(ARRAY_SIZE(a), &a); } That syntax is why array overflows remain the #1 problem with C bugs in shipped code. It isn't any better than: int foo(size_t n, int* a) { assert(5 < n); return a[5]; } int main() { int a[3]; return foo(ARRAY_SIZE(a), a); } as the array dimension has to be handled separately from the pointer. Contrast with how simple it is in D: int foo(int[] a) { return a[5]; } int main() { int[3] a; return foo(a); } and the proof is shown by array overflow bugs in the wild are stopped cold. It can be that simple and effective in C.
- TZubiri 2y ago"The DeathStation 9000" The what now?
- layer8 2y agoGoogle it.
- TZubiri 2y agoYeah, why have any type of human interaction in a forum when you can just refer your fellow brethren to the automaton.
- layer8 2y agoI’m saying this because any explanation I could offer would provide less insight than the Google results.
- TZubiri 2y agoLess insight, perhaps, but of higher quality, which is subjective. I personally find that googling stuff provides not much connection to the subject of study, very impersonal and try to avoid it. For example I did google the concept, and found this https://github.com/cousteaulecommandant/ds9k https://github.com/cousteaulecommandant/ds9k. Which is not trivial to parse, bing posited the answer as authoritative, and if you look at the code it is really nothing, it seems to be a folklore concept, and as such, it is much more aptly transmitted by speaking to a human and getting a live version than by googling an authoratitative static answer.
- bsder 2y agoNasal daemons for those of us of a slightly older vintage ...
- trealira 2y ago> The DeathStation 9000 features a conforming C implementation which is known to catch all array bounds violations. ;) That actually really does exist already with CHERI CPUs, whose pointers are tagged with "capabilities," which catch buffer overruns at runtime. https://tratt.net/laurie/blog/2023/two_stories_for_what_is_cheri.html https://tratt.net/laurie/blog/2023/two_stories_for_what_is_c... https://msrc.microsoft.com/blog/2022/01/an_armful_of_cheris/ https://msrc.microsoft.com/blog/2022/01/an_armful_of_cheris/
- Rusky 2y agoA worked example: https://github.com/pizlonator/llvm-project-deluge/blob/deluge/Manifesto.md https://github.com/pizlonator/llvm-project-deluge/blob/delug...