簡體   English   中英

std :: ofstrean不適用於-O3

[英]std::ofstrean doesn't work with -O3

下面的代碼,簡單地

1)從命令行參數獲取輸入文件名,例如in.txt

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

3)打開一個新名稱為cdf_in.txt的文件

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;
}

通過運行程序而沒有任何優化,則程序可以正常運行。 但是,通過指定-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

為什么fout-O3不兼容?

您的strcat(res, o1); 取決於res[0] == '\\0' ,這可能是正確的,但不能保證( res是未初始化的本地,因此未知/未指定其內容)。

可能是,當您不進行優化時將其初始化為零,但當您不進行優化時則被初始化為零。

您可以通過初始化res或對要復制到其中的第一項使用strcpy而不是strcat進行修復(但這仍然會導致緩沖區溢出問題,因此請參見下文,以尋求更好的選擇)。

或者,當然,您可以編寫更像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

如果您出於某種原因確實想編寫類似C的代碼,在這種情況下使用sprintf可能會更容易:

char res[30];

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

std::ofstream fout(res);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM