编译器优化如何解决这个编程问题?
How the compiler optimization solves this programming issue?
让我们考虑以下程序。
#include <stdio.h>
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
int square_of(const int value)
{
// int expr = value * value;
// return expr;
}
int main(void)
{
int test_val = 15;
int res = square_of(test_val);
fprintf(stdout, "The square of %d is %d.\n", test_val, res);
return EXIT_SUCCESS;
}
不使用优化标志的输出如下:
The square of 15 is 15.
但是,当使用优化时,例如-O1
、-O2
、-O3
,问题得到解决,输出符合预期:
The square of 15 is 0.
我不明白为什么程序会这样。是未定义的行为还是其他什么?
注意:我知道控件到达非空函数警告:
main.c: In function ‘square_of’:
main.c:10:1: warning: control reaches end of non-void function [-Wreturn-type]
10 | }
| ^
函数 square_of
没有 return
语句,而它被声明为 return 一个 int
值:使用 return 值是未定义的行为。在大多数常见的编译器上,你会得到一个不可预测的值,但标准甚至不会阻止陷阱值。
您得到原始值(没有优化)或仅 偶然 或 偶然 的 0 值,不应依赖它。
警告不可忽视。由于允许编译器假定代码不应包含 UB,因此可以自由优化可以检测到 UB 的任何代码...
这只是未定义的行为,任何事情都可能发生并且没有预期的结果 - 参见 What is undefined behavior and how does it work?
具体来说,根据 C17 6.9.1/11,它是明确未定义的行为:
If the }
that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
让我们考虑以下程序。
#include <stdio.h>
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
int square_of(const int value)
{
// int expr = value * value;
// return expr;
}
int main(void)
{
int test_val = 15;
int res = square_of(test_val);
fprintf(stdout, "The square of %d is %d.\n", test_val, res);
return EXIT_SUCCESS;
}
不使用优化标志的输出如下:
The square of 15 is 15.
但是,当使用优化时,例如-O1
、-O2
、-O3
,问题得到解决,输出符合预期:
The square of 15 is 0.
我不明白为什么程序会这样。是未定义的行为还是其他什么?
注意:我知道控件到达非空函数警告:
main.c: In function ‘square_of’:
main.c:10:1: warning: control reaches end of non-void function [-Wreturn-type]
10 | }
| ^
函数 square_of
没有 return
语句,而它被声明为 return 一个 int
值:使用 return 值是未定义的行为。在大多数常见的编译器上,你会得到一个不可预测的值,但标准甚至不会阻止陷阱值。
您得到原始值(没有优化)或仅 偶然 或 偶然 的 0 值,不应依赖它。
警告不可忽视。由于允许编译器假定代码不应包含 UB,因此可以自由优化可以检测到 UB 的任何代码...
这只是未定义的行为,任何事情都可能发生并且没有预期的结果 - 参见 What is undefined behavior and how does it work?
具体来说,根据 C17 6.9.1/11,它是明确未定义的行为:
If the
}
that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.