我想知道编译器是否有办法理解两个if
语句不能同时为真,并添加一个"隐含的其他"。例如,在此代码示例中:
int main() {
char c;
scanf_s("%c", &c, 1);
if (c == '1') {
printf("received 1\n");
}
if (c == '2') {
printf("received 2\n");
}
return 0;
}
c
无法'1'
和 '2'
,但在Visual Studio中进行编译并进行反汇编后,我发现它会检查第二个{ {1}},无论如何。
答案 0 :(得分:1)
我想知道编译器是否有办法理解两个if语句不能同时为true,并添加“隐含的else”。
是的:英特尔C编译器icc
17可以通过Matt Godbolt's Compiler Explorer进行验证,但clang和gcc似乎都没有执行此优化。
答案 1 :(得分:0)
我将在LLVM / CLANG的背景下回答,因为我对它的内部结构并不熟悉。
如果你在opt中打开mem2reg优化,它会将c视为临时而不是堆栈上的变量(在寄存器分配之前的阶段)。
在那里,优化器可以做出所需的假设,在这种情况下说第二个if在第一个内部,它将被DCE删除。
但我想不出LLVM套件中会添加“elseif”的任何传递。
对于像gcc / msvc这样的其他编译器也是如此。
答案 2 :(得分:0)
编译器理论上可以执行您建议的优化吗?是的,它绝对可以,但确保在编译器中检测此类安全场景所需的语义分析是无错误的,这绝对是非平凡的,问题是开发工作是否无法实现在其他地方更好地度过。
答案 3 :(得分:0)
由于scanf_s()
被赋予指向变量c
的指针,因此该变量不再被视为局部变量。先验,该函数可以将此指针存储在某处,并且任何其他函数(编译器未知)可以通过此指针存储某些内容,例如调用printf("received 1\n")
。
换句话说,编译器无法进行此优化,除非它知道函数scanf_s()
和printf()
正在做什么。