Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It does nothing, but is only defined when the pointers point into or one past the end of valid objects (live allocations), because that's how the standard defines the C VM, in terms of objects, not a flat byte array.


What if the objects are non-NULL, but invalid (not actually allocated)?

For example, Rust will use address 1 with length 0 for static empty strings, because 1 is a properly aligned non-null pointer.

I would imagine such strings end up being passed to C code sometimes, which may end up calling memcpy with a length of 0 on them.


> What if the objects are non-NULL, but invalid (not actually allocated)?

Still UB, since they're restricted pointers that must be valid to begin with.


This is wrong. If you do p=malloc(256), p+256 is valid even though it does not point to a valid address (it might be in an unmapped page; check out ElectricFence). Rust's non-null aligned other pointer is the same, memcpy can't assume it can be dereferenced if the size is zero. The standard text in the linked paper says the same.


also UB according to the spec, but LLVM is free to define it. e.g., clang often converts trivial C++ copy constructors to memcpy, which is UB for self-assignment, but I assume that's fine because the C++ front-end only targets LLVM, and LLVM presumably defines the behaviour to do what you'd expect.


Where I work, it is quite normal to link together C code compiled with GCC and Rust code compiled with LLVM, due to how the build system is set up.

As far as I know that disables LTO, but the build system is so complex, and the C code so large, that nobody bothers switching the C side to Clang/LLVM as well.


Still technically UB according to the proposed wording. The proposed wording only deals with allowing null pointers explicitly.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: