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

科技回声

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

GitHubTwitter

首页

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

资源链接

HackerNews API原版 HackerNewsNext.js

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

A curiously recurring lifetime issue

79 点作者 irsagent超过 1 年前

10 条评论

kentonv超过 1 年前
Author of Cap&#x27;n Proto here.<p>The main innovation of Cap&#x27;n Proto serialization compared to Protobuf is that it doesn&#x27;t copy anything, it generates a nice API where all the accessor methods are directly backed by the underlying buffer. Hence the generated classes that you use all act as &quot;views&quot; into the single buffer.<p>C++, meanwhile, is famously an RAII lanugage, not garbage-collected. In such languages, you have to keep track of which things own which other things so that everyone knows who is responsible for freeing memory.<p>Thus in an RAII language, you generally don&#x27;t expect view types to own the underlying data -- you must separately ensure that whatever does own the backing data structure stays alive. C++ infamously doesn&#x27;t really help you with this job -- unlike Rust, which has a type system capable of catching mistakes at compile time.<p>You might argue that backing buffers should be reference counted and all of Cap&#x27;n Proto&#x27;s view types should hold a refcount on the buffer. However, this creates new footguns. Should the refcounting be atomic? If so, it&#x27;s really slow. If not, then using a message from multiple threads (even without modifying it) may occasionally blow up. Also, refcounting would have to keep the <i>entire</i> backing buffer alive if any one object is pointing at it. This can lead to hard-to-understand memory bloat.<p>In short, the design of Cap&#x27;n Proto&#x27;s C++ API is a natural result of what it implements, and the language it is implemented in. It is well-documented that all these types are &quot;pointer-like&quot;, behaving as views. This kind of API is very common in C++, especially high-performing C++. New projects should absolutely choose Rust instead of C++ to avoid these kinds of footguns.<p>In my experience each new developer makes this mistake once, figures it out, and doesn&#x27;t have much trouble using the API after that.
评论 #38676806 未加载
IshKebab超过 1 年前
&gt; Is this on Cap&#x27;n Proto? Honestly, I don&#x27;t know.<p>It absolutely is. It&#x27;s a fairly basic principle that APIs should be difficult to misuse, and that fact that you made the same mistake 2&#x2F;3 times shows that it is <i>very</i> easy to misuse. In other words it is a badly designed API. At the very least it should be called ListView.<p>I am not a big fan of CapnProto. It has some neat features but it&#x27;s very complicated, full of footguns like this, and the API is extremely unergonomic.
评论 #38676747 未加载
评论 #38676876 未加载
nyanpasu64超过 1 年前
I&#x27;d say that method chaining (referential transparency, etc.) and implicit destructor calls with side effects don&#x27;t mix.<p>I have a general rule that &quot;resource&quot; types which own a heap allocation should usually be given a variable name with explicit scope (and likely even an explicit type, rather than `auto response` like in this post). This is a general guideline to avoid holding a reference to a temporary that gets destroyed, but doesn&#x27;t protect against returning a dangling reference into a resource type from a function.<p>In other places, where languages make the opposite decision (from this blog post) to <i>extend</i> the lifetime of a temporary variable with a destructor when you call methods on it, you get things like C++&#x27;s temporary lifetime extension (not a bug, note that I don&#x27;t understand it well), and footguns like Rust&#x27;s `match lock.lock().something {}` (<a href="https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;lang-team&#x2F;blob&#x2F;master&#x2F;design-meeting-minutes&#x2F;2023-03-15-temporary-lifetimes.md#lack-of-equivalence-between-if-and-match">https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;lang-team&#x2F;blob&#x2F;master&#x2F;design-me...</a>).
phendrenad2超过 1 年前
Referential transparency be damned, I guess. This feels like a inherent downside to languages where you have to manage lifetimes.
GuB-42超过 1 年前
The problem I see here is that one of the functions returns a pointer and it doesn&#x27;t use the usual pointer syntax.<p>I see no *, no &amp; and no -&gt; in the code. So I would assume everything to behave as if it was owned or even copied. Had it returned actual pointers, or pointer-like objects like iterators, it would have been more obvious.
评论 #38676799 未加载
HarHarVeryFunny超过 1 年前
Seems like someone trying to be too clever to me, and perhaps a case of premature optimization. Non-owning references are a problem waiting to happen. Even if your language&#x2F;api allows you to check if the reference is still valid before use, you can obviously forget to do so.<p>Rather than use a non-owning reference I&#x27;d rather use a design that didn&#x27;t need it, or just use a std::shared_ptr owning reference instead. I realize there are potential cases (i.e. one can choose to design such cases) of circular references where a non-owning reference might be needed to break the circular chain, or where one wants a non-owning view of a data structure, but without very careful API design and code review these are easy to mess up.
评论 #38677242 未加载
dataflow超过 1 年前
I think [[clang::lifetimebound]] would let the compiler detect this at compile time?
jimberlage超过 1 年前
Is there a good tutorial on Valgrind for beginners? It’s a tool I’ve only ever seen praised so I’m curious to play with it a bit.
评论 #38676756 未加载
评论 #38674120 未加载
plagiarist超过 1 年前
My takeaway is just the last paragraph, it sounds like Cap&#x27;n Proto is a footgun and I should use anything else.
评论 #38675770 未加载
mungaihaha超过 1 年前
Nice read