私はいくつかのCコードをリファクタリングし、分解された部品についてユニットテストを行っています(Google Testを使用しています)。 1つのスニペットがループで複数回使用されていたので、テストに公開するために、inline
というファンクションをヘッダファイルdemo.h
に組み込みました。これには他の非inline
関数の宣言も含まれています。次のように単純化されたバージョンは次のとおりです。なぜfprintfを使用する場合、インライン関数を静的宣言する必要がありますか?
#ifndef DEMO_H_
#define DEMO_H_
#ifdef __cplusplus
extern "C" {
#endif
inline void print_line(FILE* dest, const double * data, int length) {
for (int s = 0; s < length; s++)
fprintf(dest, "%lf ", data[s]);
fprintf(dest, "\n");
}
#ifdef __cplusplus
}
#endif
#endif /* MK_H_ */
私のテストコード
#include "gtest/gtest.h"
#include "demo.h"
#include <memory>
#include <array>
#include <fstream>
TEST (demo, print_line) {
std::array<double,4> test_data = {0.1, 1.4, -0.05, 3.612};
const char* testfile = "print_line_test.txt";
{
auto output_file = std::unique_ptr<FILE, decltype(fclose)*>{
fopen(testfile, "w"), fclose };
print_line(output_file.get(), test_data.data(), test_data.size());
}
std::ifstream input(testfile);
double dval;
for(const auto& v: subsequence_data) {
input >> dval;
EXPECT_EQ (v, dval);
}
EXPECT_FALSE (input >> dval) << "No further data";
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
このコードはコンパイルして-std=gnu++0x
でのMinGWグラム++ 4.8.1の下に細かい動作します。
元のCコードはこの関数を使用します。単純化されたバージョンは、次のようになります。
#include "demo.h"
void process_data(const char* fname, double ** lines, int num_lines, int line_length) {
FILE* output_file = fopen(fname, "w");
for (int i=0; i<num_lines; ++i) {
print_line(output_file, lines[i], line_length);
}
}
しかし、私は-std=c99
とMinGWのGCC 4.8.1を使用して、私のCコードをコンパイルしようとすると、私は次の警告を得る:
警告:「fprintfのをprint_line 『静的ない '静的が、インライン関数で使用される』私はまた、関連している可能性があり、後続のエラーを取得
[デフォルトで有効]:
にヘッダ内の署名を変更する `print_line」から
未定義の参照は、問題を修正するように見えます。しかし、私は問題の原因を理解していないのが好きではありません。
static
の欠如がC++テストに影響しなかったのはなぜですか?そして、実際にはfprintf
に関するエラーはどういう意味ですか?
最初の問題は、 '-std = c99'は** ** [tag:c]ではないからです。 –
@iharob私はあなたがかなり間違っていると信じています。テストコードはC++ですが、ヘッダーファイルはCで、C言語で書かれたコードで使用されています。私はこれを私の質問で非常に明確にしたと思います。 – beldaz
インライン関数は、それらがどこかで呼び出されない限り使用されず、呼び出しは(マクロと同様に)関数本体に置き換えられます。だから、あなたのコードで 'print_line'はどこにもありません。 – milevyo