- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
让我们考虑以下用 C 编写的代码块:
void foo(int i) {
if(i > 0) {
bar(i);
}
}
static void bar(int i) {
if(i > 0) {
//Do something useful
printf("FOO-BAR");
}
}
一个好的主流 C 编译器能否从 foo(int) 内部调用的 bar(int) 中优化掉不必要的 i > 0 比较?
如果是那么在什么情况下,如果不是那么为什么不呢?
最佳答案
C++ 编译器可以自由地进行任何不可观察的优化。优化器比大多数人想象的要切碎得多。 What Has My Compiler Done For Me Lately?在给定的情况下可能会发生的是 foo
将转换为:
void foo(int i) {
if(i > 0) {
printf("FOO-BAR");
}
}
这就是 VC++ 2017 所做的。事实上,它同时优化了 foo
和 bar
,并且在给出以下 MCVE 时只执行一个测试。
static void bar(int i) {
if (i > 0) {
//Do something useful
printf("FOO-BAR");
}
}
void foo(int i) {
if (i > 0) {
bar(i);
}
}
int main() {
int i;
scanf("%d", &i);
foo(i);
}
下面是生成的程序集。请注意,在从 stdin 读取 int i
后,下一条指令是 cmp
(比较)后跟 jle
(如果小于 - 则跳转或等于)。没有 foo
或 bar
在优化器中幸存下来。
int main() {
000000013F401000 sub rsp,38h
000000013F401004 mov rax,qword ptr [__security_cookie (013F403000h)]
000000013F40100B xor rax,rsp
000000013F40100E mov qword ptr [rsp+28h],rax
int i;
scanf("%d", &i);
000000013F401013 lea rdx,[i]
000000013F401018 lea rcx,[string "%d" (013F402228h)]
000000013F40101F call scanf (013F401060h)
foo(i);
000000013F401024 cmp dword ptr [i],0
000000013F401029 jle main+37h (013F401037h)
000000013F40102B lea rcx,[string "FOO-BAR" (013F402220h)]
000000013F401032 call printf (013F4010D0h)
}
000000013F401037 xor eax,eax
000000013F401039 mov rcx,qword ptr [rsp+28h]
000000013F40103E xor rcx,rsp
000000013F401041 call __security_check_cookie (013F401140h)
000000013F401046 add rsp,38h
000000013F40104A ret
关于c++ - 编译器可以优化掉不必要的比较吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48599677/
jQuery attributeContainsPrefix [name^="value"] 对比 attributeStartsWith [name|="value"] 实际区别是什么? 最佳答案
在1.1部分在RFC 6749中,有四种角色:资源拥有者、资源服务器、客户端和授权服务器。 如果客户端和资源所有者是同一实体,OAuth 是否变得多余或不必要? 例如,我有一个封闭的 API 和一个面
我有一段代码,其中有一个带有保护子句的 raise 语句: def validate_index index # Change to SizeError raise ArgumentError
我看到了这篇文章( JPA Entity Lifecycle Events vs database trigger ),但它并没有像我在这里那样明确地询问: 当我插入 PK 值为 (null) 的行时
所以,我有一段代码看起来像 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){ // Do something }
我是一名优秀的程序员,十分优秀!