std :: ofstrean不能与-O3一起使用

时间:2021-08-23 12:22:18

The following code, simply

以下代码,简单地说

1) takes an input file name from the command line argument, say in.txt

1)从命令行参数中获取输入文件名,比如in.txt

2) append the file name to "cdf_"

2)将文件名附加到“cdf_”

3) open a file with new name cdf_in.txt

3)打开一个名为cdf_in.txt的文件

4) simply read each line from (a number in each line) and send it to the output file.

4)简单地从(每行中的一个数字)读取每一行并将其发送到输出文件。

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

int main(int argc, char* argv[]) 
{
  char *ben = argv[1];    // example: in.txt
  ifstream fin (ben);
  char res[30];

  char *o1 = "cdf_";
  strcat(res, o1);
  strcat(res, ben);
  ofstream fout (res, std::ofstream::out);   // will be cdf_in.txt
  cout << res << endl;

  uint64_t num;  uint64_t sum = 0;
  while (fin >> num) {
    fout << num << endl;
  }
  return 0;
}

By running the program without any optimization, it runs normally. However, by specifying -O3, it fails to create the output file. Why???

通过运行程序而不进行任何优化,它可以正常运行。但是,通过指定-O3,它无法创建输出文件。为什么???

$ g++ -o cdf cdf.cpp
cdf.cpp: In function ‘int main(int, char**)’:
cdf.cpp:19: warning: deprecated conversion from string constant to ‘char*’
$ ./cdf in.txt
cdf_in.txt
$ ls cdf*
cdf  cdf.cpp  cdf_in.txt  cdf.py
$ cat cdf_in.txt
10
5
3
2
1

$ rm cdf_in.txt
$ g++ -O3 -o cdf cdf.cpp
cdf.cpp: In function ‘int main(int, char**)’:
cdf.cpp:19: warning: deprecated conversion from string constant to ‘char*’
$ ./cdf in.txt
cdf_in.txt
$ ls cdf*
cdf  cdf.cpp  cdf.py

Why the fout doesn't work with -O3?

为什么fout不能与-O3一起使用?

1 个解决方案

#1


Your strcat(res, o1); depends on res[0] == '\0', which may be true, but isn't guaranteed (res is an uninitialized local, so its contents aren't known/specified).

你的strcat(res,o1);取决于res [0] =='\ 0',这可能是真的,但不保证(res是未初始化的本地,因此其内容未知/指定)。

Chances are that it's being initialized to zeros when you don't do optimization, but not when you do.

当你不进行优化时,它可能会被初始化为零,但是当你没有进行优化时,它会被初始化为零。

You could fix it by initializing res, or by using strcpy instead of strcat for the first item you want to copy there (but this still leaves possible buffer overrun problems, so see below for better alternatives).

您可以通过初始化res来修复它,或者通过使用strcpy而不是strcat来复制您要复制的第一个项目(但这仍然存在可能的缓冲区溢出问题,因此请参阅下面的更好的替代方案)。

Or, of course, you could write code that's more like C++ instead of C, and use std::string instead of arrays of char.

或者,当然,您可以编写更像C ++而不是C的代码,并使用std :: string而不是char数组。

std::string fname("cdf_");
fname += argv[1];

std::ofstream fout(fname.c_str()); // just `fout(fname)` with a C++11 compiler

If you really want to write C-like code for some reason, it's probably easier to use sprintf in this case:

如果你真的想出于某些原因编写类似C的代码,在这种情况下使用sprintf可能更容易:

char res[30];

sprintf(res, "cdf_%35s", argv[1]);

std::ofstream fout(res);

#1


Your strcat(res, o1); depends on res[0] == '\0', which may be true, but isn't guaranteed (res is an uninitialized local, so its contents aren't known/specified).

你的strcat(res,o1);取决于res [0] =='\ 0',这可能是真的,但不保证(res是未初始化的本地,因此其内容未知/指定)。

Chances are that it's being initialized to zeros when you don't do optimization, but not when you do.

当你不进行优化时,它可能会被初始化为零,但是当你没有进行优化时,它会被初始化为零。

You could fix it by initializing res, or by using strcpy instead of strcat for the first item you want to copy there (but this still leaves possible buffer overrun problems, so see below for better alternatives).

您可以通过初始化res来修复它,或者通过使用strcpy而不是strcat来复制您要复制的第一个项目(但这仍然存在可能的缓冲区溢出问题,因此请参阅下面的更好的替代方案)。

Or, of course, you could write code that's more like C++ instead of C, and use std::string instead of arrays of char.

或者,当然,您可以编写更像C ++而不是C的代码,并使用std :: string而不是char数组。

std::string fname("cdf_");
fname += argv[1];

std::ofstream fout(fname.c_str()); // just `fout(fname)` with a C++11 compiler

If you really want to write C-like code for some reason, it's probably easier to use sprintf in this case:

如果你真的想出于某些原因编写类似C的代码,在这种情况下使用sprintf可能更容易:

char res[30];

sprintf(res, "cdf_%35s", argv[1]);

std::ofstream fout(res);