Przebudowuję niektóre kod C i wykonuję testy jednostkowe na wydzielonych częściach (za pomocą testu Google). Jeden fragment został użyty kilka razy w pętli, więc aby wystawić go na testowanie, podałem go jako funkcję inline
w pliku nagłówkowym demo.h
, który zawiera także deklaracje niektórych innych funkcji innych niż inline
. Uproszczona wersja jest następująca:Dlaczego funkcja inline musi być zadeklarowana jako statyczna, jeśli używa 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_ */
Mój kod testowy
#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();
}
Ten kod kompiluje i działa poprawnie pod MinGW g ++ 4.8.1 z -std=gnu++0x
.
Oryginalny kod C następnie wykorzystuje tę funkcję. Uproszczona wersja byłyby następujące:
#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);
}
}
Jednak gdy próbuję skompilować mój kod C przy użyciu MinGW GCC 4.8.1 z -std=c99
, pojawia się następujące ostrzeżenie:
ostrzeżenie: „fprintf 'jest statyczna, ale używane w funkcji inline «print_line» który nie jest statyczny [domyślnie włączona]
ja też się kolejny błąd, który może być związany:
niezdefiniowana odniesienia do `print_line”
Zmiana podpis w nagłówku do static inline void print_line ...
wydaje się rozwiązać problem. Nie podoba mi się jednak zrozumienie przyczyny problemu. Dlaczego brak testu static
nie wpłynął na test C++? A co właściwie oznaczał błąd dotyczący fprintf
?
Pierwszy problem, '-std = c99' jest nieprawidłowy, ponieważ ** TO NIE JEST ** [tag: c]. –
@iharob Uważam, że jesteś w błędzie. Kod testowy to C++, ale plik nagłówkowy to C i jest używany w kodzie napisanym w języku C. Myślę, że bardzo jasno wyjaśniłem to w moim pytaniu. – beldaz
Funkcje inline nie są używane, dopóki nie zostaną wywołane gdzieś, wtedy wywołanie zostanie zastąpione przez treść funkcji (tak jak w przypadku makr). więc w kodzie 'print_line' wskazuje się donikąd. – milevyo