diff --git a/include/aidge/utils/Log.hpp b/include/aidge/utils/Log.hpp index 6b2ace1c6aa013ae81e5144665e2edde830cdc54..cb9348dc24d1ac4c10b090e3676fabea2035a35b 100644 --- a/include/aidge/utils/Log.hpp +++ b/include/aidge/utils/Log.hpp @@ -176,6 +176,22 @@ public: } } + /** + * @struct fcloseDeleter + * @brief Custom deleter to prevent compiler warnings when using + * std::unique_ptr with FILE*. + * + * Using function pointers with attributes (e.g., __attribute__((nonnull))) + * as deleters can trigger warnings like -Wignored-attributes. By defining a + * custom deleter struct, these attributes are preserved, eliminating the + * warnings. + */ + struct fcloseDeleter { + void operator()(FILE *f) const noexcept { + std::fclose(f); + } + }; + private: static void log(Level level, const std::string& msg); static void initFile(const std::string& fileName); @@ -184,7 +200,7 @@ private: static bool mConsoleColor; static Level mFileLevel; static std::string mFileName; - static std::unique_ptr<FILE, decltype(&std::fclose)> mFile; + static std::unique_ptr<FILE, fcloseDeleter> mFile; static std::vector<std::string> mContext; }; } diff --git a/src/utils/Log.cpp b/src/utils/Log.cpp index da32a8e0ec6a3c9f27da5c47f9e6166c1fc879bc..136fcc16fe5f83f684f0686fe64105023f8cc688 100644 --- a/src/utils/Log.cpp +++ b/src/utils/Log.cpp @@ -56,13 +56,13 @@ std::string Aidge::Log::mFileName = []() { } return std::string(); }(); -std::unique_ptr<FILE, decltype(&std::fclose)> Aidge::Log::mFile {nullptr, nullptr}; +std::unique_ptr<FILE, Aidge::Log::fcloseDeleter> Aidge::Log::mFile {nullptr, Aidge::Log::fcloseDeleter()}; std::vector<std::string> Aidge::Log::mContext; void Aidge::Log::log(Level level, const std::string& msg) { if (level >= mConsoleLevel) { // Apply log level style only for console. - // Styles that were already applied to msg with fmt are kept also in + // Styles that were already applied to msg with fmt are kept also in // the log file. const auto modifier = !mConsoleColor ? fmt::text_style() @@ -94,14 +94,17 @@ void Aidge::Log::log(Level level, const std::string& msg) { } void Aidge::Log::initFile(const std::string& fileName) { - mFile = std::unique_ptr<FILE, decltype(&std::fclose)>(std::fopen(fileName.c_str(), "a"), &std::fclose); + FILE* rawFile = std::fopen(fileName.c_str(), "a"); - if (!mFile) { + if (!rawFile) { mFileName.clear(); // prevents AIDGE_THROW_OR_ABORT() to try to log into file AIDGE_THROW_OR_ABORT(std::runtime_error, "Could not create log file: {}", fileName); } + // Assign the new FILE* with the deleter + mFile = std::unique_ptr<FILE, fcloseDeleter>(rawFile, fcloseDeleter()); + const std::time_t t = std::time(nullptr); fmt::println(mFile.get(), "###### {:%Y-%m-%d %H:%M:%S} ######", fmt::localtime(t)); }