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

科技回声

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

GitHubTwitter

首页

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

资源链接

HackerNews API原版 HackerNewsNext.js

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

Detecting if an expression is constant in C

44 点作者 signa115 天前

4 条评论

sleirsgoevy1 天前
The Linux kernel has even a way to determine whether the expression is compile-time, WITHOUT aborting compilation in either case.<p>The trick is this (copied vebratim from Linux):<p>#define __is_constexpr(x) (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))<p>Explanation: if x is a constant expression, then multiplying it by zero yields a constant 0, and casting a constant 0 to void* makes a null pointer constant. And the ternary expression, if one of its sides is a null pointer constant, collapses to the type of the other side (thus the type of the returned pointer will be int*, and the sizeof will match). And if x was not constant, then the lefthand side would not be considered a null pointer constant by type inference, the type of the ternary expression will be void*, and the sizeof check will not match.<p>With a few more clever tricks, it&#x27;s even possible to implement a compile-time &quot;type ternary expression&quot;, like this: TYPE_IF(2 * 2 == 4, int, long). This is left as an exercise for the reader.
评论 #43977707 未加载
评论 #43975503 未加载
wahern1 天前
&gt; This works. But both gcc and clang warn about the enum being anonymous... even though that&#x27;s exactly what I wanted to do. And this cannot be silenced with #pragma since it&#x27;s a macro, so the warning occurs at the location where the macro is invoked.<p>You can use _Pragma instead of #pragma. E.g.<p><pre><code> #define C(x) ( \ _Pragma(&quot;clang diagnostic push&quot;) \ _Pragma(&quot;clang diagnostic ignored \&quot;-Wvisibility\&quot;&quot;) \ (x) + 0*sizeof(void (*)(enum { tmp = (int)(x) })) \ _Pragma(&quot;clang diagnostic pop&quot;) \ ) </code></pre> EDIT: Alas, GCC is a little pickier about where _Pragma is allowed so you may need to use a statement expression. Also, it seems GCC 14 doesn&#x27;t have a -W switch that will disable the anonymous enum warning.
bobbyi1 天前
I thought this would work:<p>#define C(x) (sizeof(char[x]), x)<p>sizeof is a compile-time operation so x need to be known at compile time.<p>It didn&#x27;t work as expected. It turns out there is an exception and the standard says that sizeof is actually calculated at runtime specifically for variable length arrays:<p>&gt; The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
pjc501 天前
It&#x27;s remarkable that people will say that doing this kind of thing is better than learning a language which actually lets you enforce this with the type system.<p>(or even just insist that users use the version of the language which supports &quot;constexpr&quot;!)
评论 #43974678 未加载
评论 #43976198 未加载
评论 #43974510 未加载
评论 #43974696 未加载
评论 #43975126 未加载
评论 #43977343 未加载