惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Vulnerabilities – Threatpost
aimingoo的专栏
aimingoo的专栏
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
GbyAI
GbyAI
阮一峰的网络日志
阮一峰的网络日志
Engineering at Meta
Engineering at Meta
IT之家
IT之家
V
Visual Studio Blog
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
A
About on SuperTechFans
博客园 - 聂微东
Blog — PlanetScale
Blog — PlanetScale
N
News and Events Feed by Topic
A
Arctic Wolf
WordPress大学
WordPress大学
小众软件
小众软件
C
CERT Recently Published Vulnerability Notes
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Y
Y Combinator Blog
T
Threat Research - Cisco Blogs
Latest news
Latest news
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
S
Schneier on Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
Lohrmann on Cybersecurity
Stack Overflow Blog
Stack Overflow Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy International News Feed
J
Java Code Geeks
Spread Privacy
Spread Privacy
宝玉的分享
宝玉的分享
I
Intezer
L
LangChain Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
G
GRAHAM CLULEY
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
The GitHub Blog
The GitHub Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
News and Events Feed by Topic
AWS News Blog
AWS News Blog
Attack and Defense Labs
Attack and Defense Labs
Security Archives - TechRepublic
Security Archives - TechRepublic
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

Hacker News

Introducing Claude Opus 4.7 Qwen Studio The Future of Everything is Lies, I Guess: Where Do We Go From Here? GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis Moving a large-scale metrics pipeline from StatsD to OpenTelemetry / Prometheus GitHub - Nightmare-Eclipse/RedSun: The Red Sun vulnerability repository GitHub - SethPyle376/hiraeth: Local AWS emulator focused on fast integration testing, with SQS support, SQLite-backed state, and a debug-friendly web UI. GitHub - macOS26/Agent: Any AI, replaces Claude Code, Cursor, OpenClaw. Over 18 LLM providers (Claude, OpenAI, Gemini, Ollama, Zai, HF, Qwen) wired into a native Mac app that writes code, builds Xcode projects, bumps versions, manages git, automates Safari, use AppleScript, JS or Accessibility, extend Agent! w/ MCP Servers, run tasks from your iPhone via Messages. YouTube now lets you turn off Shorts I Made a Terminal Pager Burgers | マクドナルド公式 Commands — HackerNews CLI documentation ChatGPT for Excel PiCore - Raspberry Pi Port of Tiny Core Linux Live Nation illegally monopolized ticketing market, jury finds Google Broke Its Promise to Me. Now ICE Has My Data. Founding Engineer at Adaptional | Y Combinator CRISPR takes important step toward silencing Down syndrome’s extra chromosome GitHub - saffron-health/libretto: The AI toolkit for building reliable browser automations US v. Heppner (S.D.N.Y. 2026) no attorney-client privilege for AI chats [pdf] Unexpected €54k billing spike in 13 hours: Firebase browser key without API restrictions used for Gemini requests Retrofitting JIT Compilers into C Interpreters IPv6 – Google The Accursèd Alphabetical Clock Cybersecurity Looks Like Proof of Work Now Fragments: April 14 Cal.com Goes Closed Source: Why AI Security Is Forcing Our Decision | Cal.com - Scheduling Software for Online Bookings Laravel raised money and now injects ads directly into your agent When moving fast, talking is the first thing to break Too much Discussion of the XOR swap trick – Heather Cafe Introduction to Spherical Harmonics for Graphics Programmers The Grand Line Building a Z-Machine in the worst possible language High-Level Rust: Getting 80% of the Benefits with 20% of the Pain GitHub - duguyue100/midnight-captain: Inspired by Midnight Commander, tailored to my taste. How to build a `git diff` driver · Jamie Tanna | Software Engineer Center for Responsible, Decentralized Intelligence at Berkeley The Local Universe’s Expansion Rate Is Clearer Than Ever, but Still Doesn’t Add Up - A new synthesis of astronomical measurements confirms a persistent mismatch that could point to physics beyond current models The air throughout our homes is infused with microplastics. But there are things you can do to breathe less of them The disturbing white paper Red Hat is trying to erase from the internet – OSnews The Future of Everything is Lies, I Guess: Annoyances ‘Abhorrent’: the inside story of the Polymarket gamblers betting millions on war Productive procrastination — Max van IJsselmuiden maps, territory and LMs 447 Terabytes per Square Centimetre at Zero Retention Energy: Non-Volatile Memory at the Atomic Scale on Fluorographane Show HN: Pardonned.com – A searchable database of US Pardons 20 Years on AWS and Never Not My Job The Seasons are Wrong Artemis II crew splashes down near San Diego after historic moon mission We gave an AI a 3 year retail lease in SF and asked it to make a profit | Andon Labs How a dancer with ALS used brainwaves to perform live On filing the corners off my MacBooks Installing every* Firefox extension OpenClaw’s memory is unreliable, and you don’t know when it will break Steve Blank Nowhere Is Safe Chimpanzees in Uganda locked in vicious 'civil war', say researchers watgo - a WebAssembly Toolkit for Go linux/Documentation/process/coding-assistants.rst at master · torvalds/linux GitHub - callumlocke/json-formatter: Makes JSON easy to read. Founding Product Engineer at Bild AI | Y Combinator A compelling title that is cryptic enough to get you to take action on it GitHub - Keychron/Keychron-Keyboards-Hardware-Design: Industrial design files for Keychron keyboards and mice. 100+ models with CAD assets in STEP, DXF, DWG, and PDF. Source-available, with commercial use allowed for original compatible accessories within the license terms. [ANNOUNCE] WireGuardNT v0.11 and WireGuard for Windows v0.6 Released 1D-Chess Helium Is Hard to Replace Cooperative Vectors Introduction | Evolve Keeping a Postgres queue healthy — PlanetScale Our response to the Axios developer tool compromise Do Americans read print books, e-books or audiobooks more? The Zettelkasten Method in Obsidian: A Practical Setup Guide Artemis II Is Competency Porn and We Are Starving For It WeakC4 Flight Viz — Cockpit View A Mexican surveillance giant you’ve never heard of is now watching the U.S. border Surelock: Deadlock-Free Mutexes for Rust RISC-V 101 – what is it and what does it mean for Canonical? | Ubuntu The Problem That Built an Industry How Much Linear Memory Access Is Enough? | Solidean Investigating Split Locks on x86-64 Simplest hash functions Sybilproof reputation mechanisms (2005) [pdf] What is a property? How Complex is my Code? Static code analysis in Kotlin — tools overview Toffoli gates are all you need PGLite evangelism dcmake: a new CMake debugger UI Clojure on Fennel part one: Persistent Data Structures Fragments: April 2 Python Release Python install manager 26.1 The Life and Death of the Book Review - Liberties Introducing Database Traffic Control — PlanetScale Bitcoin miners are losing $19,000 on every BTC produced as difficulty drops 7.8% God sleeps in the minerals Building slogbox Apple Silicon and Virtual Machines: Beating the 2 VM Limit Who was “Not Even Wrong” first? Pokemon Evolution Vs Darwinian Evolution The APL Programming Language Source Code
Things C++26 define_static_array can’t do
2026-04-26 · via Hacker News

We’ve seen previously that it’s not possible to create a constexpr global variable of container type, when that container holds a pointer to a heap allocation. It’s fine to create a global constexpr std::array, or even a std::string that uses only its SSO buffer; but you can’t create a global constexpr std::vector or std::list (unless it’s empty) because it would have to hold a pointer to a heap allocation.

Think of constexpr evaluation as taking place “in the compiler’s imagination.” Since C++20 it’s fine to use new and delete at constexpr time; but there’s a firewall between constexpr evaluation and real, material runtime existence. You can’t, at runtime, get a pointer to a heap allocation that was made only “in the compiler’s imagination,” any more than you can get a pointer to a local variable of a stack frame that was made only “in the compiler’s imagination.” So none of these snippets will compile:

constexpr int *f() { int i = 42; return &i; }
constinit int *p = f(); // error

constexpr int *f() { return new int(42); }
constinit int *p = f(); // error

constexpr std::vector<int> f() { return {1,2,3}; }
constinit std::vector<int> p = f(); // error

But if you can compute a std::vector<int> at constexpr time, then you can persist its contents into a global constexpr std::array of the appropriate size. The appropriate size is just the .size() of the vector you computed, of course. So we have what’s become known as the “constexpr two-step” (Godbolt):

constexpr std::vector<int> f() { return {1,2,3}; }

constinit auto a = []() {
  std::array<int, f().size()> a;
  std::ranges::copy(f(), a.begin());
  return a;
}();

Thanks to Barry Revzin’s P3491 (June 2025) and Jason Turner’s “Understanding the Constexpr 2-Step” (C++ On Sea 2024) for the term “constexpr two-step.” Jason’s talk deals with a specific formula in which instead of repeating — and repeatedly evaluating — f() in the body of the lambda, we factor it out into a template argument (Godbolt):

constexpr std::vector<int> f() { return {1,2,3}; }

template<auto B>
consteval auto to_array() {
  // MAGIC NUMBER WARNING!
  constexpr auto v = B() | std::ranges::to<std::inplace_vector<int, 999>>();
  std::array<int, v.size()> a;
  std::ranges::copy(v, a.begin());
  return a;
}

constinit auto a = to_array<[]() { return f(); }>();

C++26 will introduce a new and improved tool for this kind of compile-time array generation. It’s spelled std::define_static_array. In C++26 you can just write this (Godbolt):

constexpr std::vector<int> f() { return {1,2,3}; }
constinit std::span<const int> sp = std::define_static_array(f());

This call to define_static_array returns a span over a static-storage constant array of three ints. Basically this is asking the compiler to take the data it’s come up with “in its imagination” and write down a copy of it in the object file. This is much cleaner and more compile-time-efficient than the “two-step”!

Unfortunately, if I understand it correctly, C++26 define_static_array does not (yet?) support several things that you can do using the “two-step.” Here are a few such things.

1. Non-structural types

std::define_static_array is defined in terms of std::meta::reflect_constant(e), which C++26 defines as std::meta::template_arguments_of(^^TCls<e>)[0] for some invented template TCls. That is, reflect_constant (and thus define_static_array) is defined only for structural types. int is a structural type, and thus we can write the code above. But we cannot write

using OInt = std::optional<int>;
constexpr std::vector<OInt> f() { return {1,2,3}; }
std::span<const OInt> sp = std::define_static_array(f());

because optional<int> is not a structural type. Nor are string, string_view, span itself… There are many types that can’t be materialized using define_static_array, even though they work fine with the “constexpr two-step” (Godbolt).

2. Pointers to string literals

Because reflect_constant is defined in terms of TCls<e>, not only must the type of e be structural, but each particular value e in the array must be suitable for use as a template argument. const char* is a structural type, but if that pointer points to a string literal, then it’s not suitable for use as a template argument. So we can use define_static_array to make an array of null pointers:

constexpr std::vector<const char*> f() { return {nullptr, nullptr, nullptr}; }
std::span<const char *const> sp = std::define_static_array(f());

but it cannot make an array of pointers to literals:

constexpr std::vector<const char*> f() { return {"a", "b", "c"}; }
std::span<const char *const> sp = std::define_static_array(f());

On the other hand, the “constexpr two-step” has no problem with string literals (Godbolt).

3. Move-only types

In order to create a template parameter object representing e, we must make a copy of e ([temp.arg.nontype]/4). Therefore NTTP types must be copyable. You can (with care) use the two-step to create a static array of move-only type:

constexpr auto a = []() {
  std::array<MoveOnly, f().size()> a;
  std::ranges::copy(f() | std::views::as_rvalue, a.begin());
  return a;
}();

but you cannot do the same with define_static_array. (Godbolt.)

The above snippet, like all my other examples of the “two-step,” never actually uses move-construction; it uses default construction followed by assignment. This is unsatisfying, and prevents the two-step from creating e.g. an array of reference_wrapper. define_static_array, on the other hand, does not use default-construction (Godbolt). Can we rework the two-step to eliminate the default-constructibility requirement? I imagine we can, but at the moment I don’t see how.

4. Make the array mutable

define_static_array allocates its array in rodata and gives you a span<const T> over it. This allows the compiler to do cool things, like point multiple invocations of define_static_array at the same backing array (Godbolt). In fact, the compiler is actually required to do that, because reflect_constant is defined in terms of a template parameter object which for all intents and purposes behaves like an inline variable: there is guaranteed to be only one template parameter object with a given type and value in the whole program (Godbolt).

Treating template parameter objects as inline variables means the compiler must combine such objects when they have the same type and value (optimization! hooray!) but sadly also forbids an otherwise sufficiently smart compiler from combining such objects when their types are merely similar. Godbolt:

template<auto V> auto tpo() { return std::span(V); }
template<auto V> auto tpo2() { return std::span(V); }

const void *p1 = tpo<std::array<signed char,3>{1,2,3}>().data();
const void *p2 = tpo2<std::array<signed char,3>{1,2,3}>().data();
const void *p3 = tpo<std::array<unsigned char,3>{1,2,3}>().data();
const void *p4 = tpo<std::array<char,3>{1,2,3}>().data();

All four of these pointers point to arrays of the three bytes 01 02 03. p1 and p2 are required to point to the same byte; p3 and p4, since they point to std::array objects of different types, are required to point to different arrays. The compiler isn’t allowed to coalesce p3 and p4, the way it’s allowed to coalesce the backing arrays of differently typed initializer_lists (Godbolt).

But (hooray! and thanks to Tim Song for correcting me on this!) there is a special case specifically for the “template parameter objects of array type” created by reflect_constant_array and define_static_array. These objects are permitted ([intro.object]/9.3) to overlap or be coalesced, just like initializer_lists and string literals. Clang trunk isn’t smart enough to coalesce potentially non-unique objects; therefore the Clang reference implementation of C++26 Reflection doesn’t coalesce these array objects either; but it’s not the paper standard’s fault. Godbolt:

const void *p1 = std::define_static_array(std::vector<signed char>{1,2,3}).data();
const void *p2 = std::define_static_array(std::list<signed char>{1,2,3}).data();
const void *p3 = std::define_static_array(std::vector<unsigned char>{1,2,3}).data();
const void *p4 = std::define_static_array(std::vector<char>{1,2,3}).data();

All four of these pointers point to arrays of the three bytes 01 02 03. p1 and p2 are required to point to the same byte; p3 and p4 are permitted, but not required, to point to different arrays. In practice Clang makes them different; GCC, once it implements define_static_array, will presumably make them the same.

However, template parameter objects are invariably const! Therefore, you cannot use define_static_array to produce a constinit-but-mutable array, the way you can with the “constexpr two-step.” It seems to me perfectly reasonable to want a magic consteval function that says, “Please generate me a mutable array in static storage with these contents” — specified as a constexpr-time vector<int> — “and give me a span over it”:

template<class R>
consteval auto define_mutable_static_storage_array(R&& r)
    -> std::span<std::ranges::range_value_t<R>>;

Perfectly reasonable to want such an API; but C++26 define_static_array fundamentally isn’t that API. It can’t produce mutable data: it can’t produce anything except pointers into (potentially non-unique) template parameter objects, which behave like const inline variables.

Conclusion

In short, define_static_array is constitutionally unsuited for some conspicuous use-cases. I’m not sure what this means for the future. I’m sure we don’t want to require people to use the “constexpr two-step” forever; but define_static_array doesn’t seem suited to replace all of its uses — certainly not in C++26, and I don’t see how it could be extended in the future to solve any of the problems I outlined above.

I imagine the answer is not “define_static_array will solve all your problems today,” nor “a new and improved define_static_array will solve all your problems in C++XY,” but rather “C++XY will introduce a new and different facility for manipulating static storage” — possibly related to the as-yet-unstandardized code-generation side of reflection — and we’ll use that new facility to solve some (but perhaps not all) of the above problems.


UPDATE: Actually, problems (1), (2), and (3) all stem from define_static_array’s requirement that each element be usable as an NTTP. Barry Revzin’s P3380R1 “Extending support for class types as NTTPs” (December 2024) lays out a plan that would permit the programmer to mark their own types as explicitly structural, thus (if accepted) addressing all three of those problems. On the other hand, making a user-defined type explicitly structural per P3380R1 seems to involve pretty arcane programming. The “constexpr two-step” stays general by staying above the fray: it simply never requires anything to be encoded as a template argument.