[英]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.