From 4082e824669d63eb61fee81424e179853e241c0e Mon Sep 17 00:00:00 2001 From: Brad Arant Date: Sat, 22 Aug 2026 19:52:44 -0700 Subject: [PATCH] Fix Exception default file/line always reporting Exception.h itself __FILE__/__LINE__ are preprocessor macros - as default argument values in the header they expand once, at the header declaration site, not at each call site. Every throw relying on the defaults (all but File.cpp, which passed them explicitly) reported Exception.h itself instead of the real error location. Switched the defaults to std::source_location::current(), which the C++20 standard specifically defines to evaluate at the call site when used as a default argument - unlike macros. Kept the same 4-parameter signature so every existing call site, including ones that pass __FILE__/__LINE__ explicitly, is unaffected. Verified two ways: full-repo compile pass (identical result to before, 13/20 clean, same pre-existing StreamReader.h-blocked failures, nothing new broken); a real runtime test - a throw relying on defaults from a known line correctly reported that exact file/line via the caught exceptions .file/.line members. Test file not included in this commit. --- Exception.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Exception.h b/Exception.h index 55e7883..51c7b8c 100644 --- a/Exception.h +++ b/Exception.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace coreutils { @@ -15,7 +16,20 @@ namespace coreutils { class Exception { public: - Exception(std::string text, std::string file = __FILE__, int line = __LINE__, int errorNumber = errno); + /// + /// file/line default to the caller's actual location. std::source_location::current() + /// is specifically defined by the standard to evaluate at the call site when used as a + /// default argument - unlike __FILE__/__LINE__ (preprocessor macros, which were used + /// here previously and always expanded to this header's own declaration line instead + /// of the real throw site, since macro expansion happens before the compiler even sees + /// "default argument" as a concept). Explicit callers (e.g. throw Exception(msg, + /// __FILE__, __LINE__)) are unaffected - the signature is unchanged. + /// + + Exception(std::string text, + std::string file = std::source_location::current().file_name(), + int line = std::source_location::current().line(), + int errorNumber = errno); std::string className; std::string file;