【发布时间】:2023-03-17 15:12:01
【问题描述】:
我有一些 C 代码,经过艰苦的努力,在 Excel 中手动执行操作后,我验证了我通过 gcc -O0 编译的可执行文件运行正确,但如果我使用 -O2 编译,我的输出很糟糕。
什么可能导致这种情况? 到目前为止,我已经将问题追踪到它读取数据的位置, 这是它读取的输入文件的总集合,我读取的每一行数据(来自文本文件的数字)我立即打印到标准输出并重定向到一个名为 O0.txt 或 O2.txt 的文件中。如果我比较这些文件,我会发现在我期望看到完全相同的数字时存在显着差异。
这是 gcc-4.3.4 suse linux
这里有一个 sn-p 代码,用于显示什么不适用于 -O2 但它确实适用于 -O0 基于 printf 并将输出重定向到 O0.txt 或O2.txt
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# define ZZ 8192
double x[9000];
double y[9000];
double z[2][17][20][3600];
void Read_Data ( FILE *fp, const int R, const int S, const int T, const int type, const int M )
{
char line[ZZ];
int count;
double a, b, c, d, e, f, g, h;
for ( r = 0; r < 12; r++ ) /* skip past header */
fgets( line, LS, fp );
for ( r = 0; r < R; r++ )
{
for ( s = 0; s < S; s++ )
{
for ( t = 0; t < T; t++ )
{
sscanf( line, "%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", &a, &b, &c, &d, &e, &f, &g, &h );
if (( a == 0 ) && ( b == 0 ))
x[t] = 1e-9;
else
x[t] = a*a + b*b;
if (( g == 0 ) && ( h == 0 ))
y[t] = 1e-9;
else
y[t] = g*g + h*h;
printf("%18.12e %18.12e %18.12e %18.12e\n", a, b, c, d );
fgets( line, ZZ, fp );
}
if ( type == 1 )
{
z[0][M][r][s] = Find_Median( x, T );
z[1][M][r][s] = Find_Median( y, T );
}
else if ( type == 2 )
{
sum_x = 0; sumy = 0;
for ( tt = 0; tt < T; tt+ )
{
sumx += x[tt];
sumy += y[tt];
}
z[0][M][r][s] = sumx / ((double)T);
z[1][M][r][s] = sumy / ((double)T);
}
}
}
}
int main ( int argc, char *argv[] )
{
FILE *fpi;
Parse_Command_line( argc, argv );
/* other code here */
T has value of 10
S has value of 10
R has value of 180
/* other code here */
fpi = fopen("mydata", "r" );
for ( m = 0; m < 17; m++ )
{
Read_Data( fpi, R, S, T, m);
}
/* other code here */
return 0;
}
【问题讨论】:
-
for ( r = 0; r < 12; r++ )r定义在哪里? -
sscanf( line, "%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", &a, &b, &c, &d, &e, &f, &g, &h );你使用了%d但a是double -
相信我
r是定义的,这是一个sn-p的代码。仅使用了-O2 -lm -Wall的编译标志,并且有 zero 警告。因为我必须混淆代码并更改变量名称才能将其发布在这里,所以上面的文本中肯定会有一些小错误,例如scanf -
我已确认 SLES 11.4 x86_64 中的系统编译器 -O2 和 gcc-4.3-4 存在问题,但在使用 gcc 4.8 的 SLES 12.3 中不会出现问题.5.这会被认为是编译器问题还是错误?
标签: gcc optimization