On Windows, fmtlib can throw an exception when writing to a FILE* handle that's been redirected to the NUL device (Windows' equivalent of /dev/null).
This occurs when fmtlib is in unicode mode -- e.g. you're building with Visual Studio with FMT_UNICODE defined, or with clang -- because the WriteConsoleW() function fmtlib calls will fail if it's passed a file handle that's not actually a console. Unfortunately on Windows _isatty() is not a robust test for determining if a given fd is a console.
I would suggest calling GetConsoleMode() instead (or perhaps in addition to the _isatty check, depending on your level of paranoia!). This is how the UCRT itself determine whether it should call WriteConsoleW -- if you have the Windows SDK installed, you can check the source at Source/<version>/ucrt/lowio/write.cpp.
To repro:
#include <cstdio>
#define FMT_UNICODE 1
#include <fmt/core.h>
int main() {
fmt::print("crash!\n"); // throws exception if stdout has been redirected to NUL
FILE* fp = std::fopen("NUL", "w");
fmt::print(fp, "crash!\n"); // throws exception
}
On Windows, fmtlib can throw an exception when writing to a
FILE*handle that's been redirected to theNULdevice (Windows' equivalent of/dev/null).This occurs when fmtlib is in unicode mode -- e.g. you're building with Visual Studio with
FMT_UNICODEdefined, or with clang -- because theWriteConsoleW()function fmtlib calls will fail if it's passed a file handle that's not actually a console. Unfortunately on Windows_isatty()is not a robust test for determining if a given fd is a console.I would suggest calling
GetConsoleMode()instead (or perhaps in addition to the_isattycheck, depending on your level of paranoia!). This is how the UCRT itself determine whether it should callWriteConsoleW-- if you have the Windows SDK installed, you can check the source atSource/<version>/ucrt/lowio/write.cpp.To repro: