I am refactoring some C code and performing unit testing on the factored out parts (using Google Test). One snippet was used several times in a loop, so in order to expose it to testing I factored it out as an inline
function in a header file demo.h
which also includes declarations of some other non-inline
functions. A simplified version is as follows:
#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_ */
My test code
#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();
}
This code compiles and runs fine under MinGW g++ 4.8.1 with -std=gnu++0x
.
The original C code then makes of use of this function. A simplified version would be the following:
#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);
}
}
However, when I try to compile my C code using MinGW GCC 4.8.1 with -std=c99
, I get the following warning:
warning: 'fprintf' is static but used in inline function 'print_line' which is not static [enabled by default]
I also get a subsequent error, which may be related:
undefined reference to `print_line'
Changing the signature in the header to static inline void print_line ...
appears to fix the problem. However, I don't like not understanding the cause of the issue. Why did the lack of static
not affect the C++ test? And what did the error regarding fprintf
actually mean?