5 ms·
C++ needs spatial memory safety. It can be added without greatly changing the semantics of the language. Temporal memory safety is much harder.
by david2ndaccount 4y ago
C++ needs spatial memory safety. It can be added without greatly changing the semantics of the language. Temporal memory safety is much harder.
- deleted 4y ago[deleted]
- olliej 4y agoLibc++ for example is doing just that, it was on HN a while back and generated many many complaints. It doesn’t help though that there’s no way to distinguish a pointer from an array, nor get the length of an array (because you aren’t guaranteed an array is a c++ array with a prefix header or a c style array with a separate size), and given a lot of c++ is still pointers - for example the semantics of iterators makes it hard to be both bounds safe and fast, which means c++ iterators can easily go out of bounds or into random memory in the face of mutation. Now obviously we generally agree mutating something while iterating it is bad, but the c++ iterators semantics makes detecting and stopping that extremely expensive because it’s fundamentally designed around reusing old code that was just incrementing pointers.
- david2ndaccount 4y agoI’m not sure what you mean by “there’s no way to distinguish a pointer from an array”. Arrays and pointers in C and C++ are distinct types, although arrays will decay to a pointer in an expression context (and there is the whole problem with arrays as function parameters being rewritten to pointers which adds to the confusion). C with VLAs can actually express the length of a pointed to array, with the following example: #include <stdio.h> // See the linux kernel for a version that verifies // `x` is actually an array. #define arrlen(x) (sizeof(x)/sizeof(x[0])) void foo(const int x, int(*y)[x]){ printf("%zu\n", arrlen(*y)); } int main(){ int a[3]; foo(arrlen(a), &a); return 0; } If you compile and run the above code, you will see that it correctly prints the length of the array - 3. Unfortunately, the syntax is awkward and most C/C++ programmers would be stumped by the actual syntax for a pointer to an array. There is also no help that the correct length is passed.
- olliej 4y agoFirst up, this is just invalid in C++, because C++'s type system has a bunch of the foot guns removed from it. In C this will probably work, but only because VLAs in C are broken by design - VLAs are not part of the type system, which means there is no actual required relationship between the size of the array - even when statically known as in your example - and the parameters to the function. So yes your example will print 3, but that's because it will print whatever you pass in for x. So I can equally do: foo(500, &a); and that's valid, and I would put money on not producing even a warning. Again because VLAs aren't part of the type system I could also do: foo(5, malloc(1)); and that should work fine as well, because VLAs are again not real. Moreover this is also kind of missing the point: I said there is no way to distinguish a pointer from an array allocation, and your example is not using a pointer or an array, it is using a pointer and an additional length value - and yes, the correct thing to do is to have a struct containing both of those, or probably better a struct with trailing storage. Either way the C or C++ type system does not distinguish between a pointer to an object, or a pointer to an array of N (including potentially 1) objects, and you, the programmer need to do this yourself without language support.