TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Passing nothing is surprisingly difficult

180 点作者 kingkilr超过 1 年前

12 条评论

kazinator超过 1 年前
There is no problem with memcpy other than that you can&#x27;t use a null pointer. You can memcpy zero bytes as long as the pointer is valid. This works in a good many circumstances; just not circumstances where the empty array is represented by not having an address at all.<p>For instance, say we write a function that rotates an array: it moves the low M bytes to the top of the array, and shuffles the remaining M - N bytes down to the bottom. This function will work fine with the zero byte memmove or memcpy operations in the special case when N == 0, because the pointer will be valid.<p>Now say we have something like this:<p><pre><code> struct buf { char *ptr; size_t size; }; </code></pre> we would like it so that when the size is zero, we don&#x27;t have an allocated buffer there. But we&#x27;d like to support a zero sized memcpy in that case: memcpy(buf-&gt;ptr, whatever, 0) or in the other direction likewise.<p>We now have to check for buf-&gt;ptr being buf in the code that deals with resizing.<p>Here is a snag in the C language related to zero sized arrays. The call malloc(0) is allowed to return a null pointer, or a non-null pointer that can be passed to free.<p>oops! In the one case, the pointer may not be used with a zero-sized memcpy; in the other case it can.<p>This also goes for realloc(NULL, 0) which is equivalent to malloc(0).<p>And, OMG I just noticed ...<p>In C99, this was valid realloc(ptr, 0) where ptr is a valid, allocated pointer. You could realloc an object to zero.<p>I&#x27;m looking at the April 2023 draft (N3096). It states that realloc(ptr, 0) is undefined behavior.<p>When did that happen?
评论 #39022268 未加载
评论 #39025325 未加载
评论 #39022311 未加载
cbarrick超过 1 年前
Useful context on the Rust side is this issue [1]. It sounds like some of the author&#x27;s concerns are addressed already.<p>[1]: <a href="https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;unsafe-code-guidelines&#x2F;issues&#x2F;472">https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;unsafe-code-guidelines&#x2F;issues&#x2F;4...</a>
评论 #39016654 未加载
评论 #39022490 未加载
kevingadd超过 1 年前
A fun additional twist to this is that dereferencing nullptr is valid in WebAssembly, and actual data can in fact end up there, though ideally it never will.<p>If you ensure that the &#x27;zero page&#x27; (so to speak) is empty you can also exploit this property for optimizations, and in some cases the emscripten toolchain will do so.<p>i.e. if you have<p><pre><code> struct MyArray&lt;T&gt; { uint length; T items[0]; } </code></pre> you can elide null pointer checks and just do a single direct bounds check before dereferencing an element, because for a nullptr, (&amp;ptr-&gt;length) == nullptr, and if you reserve the zero page and keep it empty, (nullptr)-&gt;length == 0.<p>this complicates the idea of &#x27;passing nothing&#x27; because now it is realistically possible for your code to get passed nullptr on purpose and it might be expected to behave correctly when that happens, instead of asserting or panicking like it would on other (sensible) targets
评论 #39022099 未加载
评论 #39020940 未加载
评论 #39021635 未加载
评论 #39020553 未加载
matheusmoreira超过 1 年前
I&#x27;m dealing with the exact same issues right now in my project, this post is very enlightening.<p>&gt; But suppose we want an empty (length zero) slice.<p>So is there an actual rationale for this? I&#x27;ve written the memory allocator and am in the process of developing the foreign interface. I&#x27;ve been wondering if I should explicitly support zero length allocations. Even asked this a few times here on HN but never got an answer. It seems to be a thing people sort of want but for unknown reasons.
评论 #39021139 未加载
swiftcoder超过 1 年前
It&#x27;s obviously too late to change this in Rust&#x27;s case, but I wonder whether being able to differentiate between None and the empty slice is actually a necessary property in general?<p>There are a bunch of languages where empty arrays are &quot;falsy&quot;, and in those it&#x27;s not recommendable to use the two to differentiate valid states. Feels like the same could apply here
评论 #39026264 未加载
评论 #39025200 未加载
评论 #39029993 未加载
vardump超过 1 年前
Fun times with buggy kernel drivers.<p>Pass something with a 0 length, pointing to NULL. Enjoy your blue screens and kernel panics.
pizlonator超过 1 年前
It’s so silly to talk about C not allowing null on memcpy. That’s a thing the spec says, I guess?<p>The solution is clear: just ignore the C spec. It’s total garbage. Of course you can memcpy between any ptr values if the count is zero and those ptr values don’t have to point to anything.
评论 #39026312 未加载
评论 #39032833 未加载
SonOfLilit超过 1 年前
What a wonderfully subtle issue.
pyrolistical超过 1 年前
How does zig handle this? Does it just have its own slice representation that gets compiled away? Or does it disallow zero length slices?
评论 #39024546 未加载
评论 #39024671 未加载
stealthcat超过 1 年前
In ML the problem is passing 0D scalar tensor as 1D 1-element tensor.
bhakunikaran超过 1 年前
Quite intriguing
hackyhacky超过 1 年前
&gt; Passing nothing is surprisingly difficult<p>From the title, I assumed that this article was going to be about either (a) permissive grading standards at university or (b) chronic constipation.
评论 #39021025 未加载