问题标签 [constantfolding]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 预处理阶段的恒定折叠
我有一段需要去混淆的 C 代码。它包含一堆棘手的宏。我通过 C 预处理器和缩进运行代码,现在它看起来类似于:
为了简化进一步的分析,我正在寻找一些可以折叠代码中所有常量的工具。我知道 C 预处理器无法做到这一点,并且将在编译阶段执行常量折叠优化。但是源代码呢?
Shell 脚本也很受欢迎,因为我怀疑这可能是唯一的方法。
c++ - 避免打开类型以允许不断折叠
我试图找到一个类层次结构,它允许为处理器寄存器和操作实现占位符。它还应该允许在运行时折叠常量。为了简单起见,我只看一个操作,这里是乘法。占位符和常量应该可以统一访问,即有一个共同的基类。
下面的代码定义了以下类:
class A
: 占位符(寄存器)和常量的基类
class B
:寄存器的占位符(其结构包含它的名称)
class C
: 所有常数的基数
class CI
: int
常数
class CF
: float
常数
我在上面的代码中遇到的问题是函数Aptr mul_const( const Cptr& cp1 , const Cptr& cp2 )
。它基本上包含所有可能的常量类型组合的类型切换。它有效,但我想知道这是否可以更优雅地完成?
c - C 标准是否要求编译时常量表达式求值?
例如,是
有效标准 C? 对于标准的部分或所有版本?
我对编译器是否可以处理它不感兴趣,但它是否是标准 C 的一部分。
c - 可变长度数组折叠成常量数组
这会得到警告:
可变长度数组折叠成常量数组作为扩展。
你能帮忙解决这个问题吗?
perl - Perl 内部结构和 Moose:常量折叠优化
我一直对 Perl 执行的常量折叠优化感到好奇,但是当代码涉及 Moose 时,可能不会执行常量折叠(如果我错了,请纠正我)。
我有 Moose 代码,其中包含以下方法:
当我运行时,perl -MO=Deparse ./program.pl
我得到几乎相同的代码行:
我想知道为什么 Perl 没有优化32-8
as 24
?Perl 没有这样做有什么真正的原因吗(也许 Moose 子系统让生活变得更艰难?)。
如果有帮助,我运行 Perl (v.5.14.2)
c - gcc 复杂常量折叠
gcc 似乎对复杂的常量折叠有一些限制。这是一个例子:
当以 -O3 优化级别(gcc 4.8)运行时,它会很好地展开 DJBHash 中的循环,并在编译期间计算该字符串的哈希值。
但是,当使字符串变长一个字符时return DJBHash("012345678901234567");
,它不再折叠它并生成一个带有条件跳转指令的循环。
我想将任意长度的文字字符串折叠为其哈希值作为编译时间常数。
这可以做到吗?
澄清
我的问题是关于 gcc 上的常量折叠优化(请参阅标题 - 请不要删除gcc和编译器标签)
这里的许多答案试图用模板或 constexpr 解决问题。很高兴了解这些选项,并感谢您发布它们以造福所有人。但是,他们没有直接回答我的问题。
实际上,我正在开发一个 gcc 端口,因此如果需要,我可以更改和构建 gcc 源代码。但我仅限于 C,我想在这个范围内解决这个问题。
java - JVM 是否进行运行时常量折叠?
如果我有两个在编译时已知的常量,Java 编译器会将它们折叠起来。
在运行时,myFunction 将返回 34 + myVariable,并且不需要像在编译时那样计算 2*17。
我的问题是:如果直到运行时才知道常量,它会做同样的事情吗?我相信这被称为运行时代码专业化。
如果 foo 和 bar 在对象的构造函数中被初始化为 2 和 17,myFunction 是否会专门返回 34 + myVariable,或者它是否仍会在每次调用函数时计算 foo*bar,即使 foo*bar 永远不会改变?
*编辑:我指的是最新版本的 JVM,1.7.0_45。
c - log(10.0) 可以编译但 log(0.0) 不能使用未定义的引用?
对于以下C源代码:
当我用 编译时gcc -lm
,我得到:
但是,如果我替换log(0.0)
为log(10.0)
,那么它可以编译成功。
我不太明白这一点,因为无论它们是否具有数学意义,它们都应该编译——没有语法错误。谁能解释一下?
以防万一,我的gcc -v
输出:
请注意,这个问题是关于常量折叠的,但建议的重复问题是关于缺少链接库的。
c - 为什么在 C for 循环的条件中使用表达式而不是常量?
在许多编程比赛中,我看到人们编写这种类型的for
-loop
除非我遗漏了什么,否则这与
为什么要使用(1 << 7)
版本?
每次计算条件不是不必要的开销吗?
c++ - 为什么 GCC 为 C++ 更有效地实现 isnan()比C?
这是我的代码:
如果我#include <cmath>
得到这个程序集:
这是相当聪明的:如果 x 与自身的比较是无序的,则ucomisd设置奇偶校验标志,这意味着 x 是 NAN。然后setp将奇偶校验标志复制到结果中(只有一个字节,因此初始清除%eax
)。
但如果我#include <math.h>
得到这个程序集:
现在代码没有内联了,__isnan
函数肯定没有快了ucomisd
指令快,所以我们进行了一次跳转,没有任何好处。如果我将代码编译为 C,我会得到同样的结果。
现在,如果我将isnan()
调用更改为,无论我包含哪个标头__builtin_isnan()
,我都会得到简单的指令指令,并且它也可以在 C 中使用。ucomisd
同样,如果我只是return x != x
.
所以我的问题是,为什么 C<math.h>
头文件提供的实现效率isnan()
低于 C++<cmath>
头文件?人们真的期望使用__builtin_isnan()
,如果是,为什么?
我在 x86-64 上使用-O2
和-O3
优化测试了 GCC 4.7.2 和 4.9.0。