error C3861: '__builtin_FILE': identifier not found (MSVC 19)
Describe the bug When compiling the project using MSVC, and macro-free mode I get the following errors:
D:\CLion Projects\Proj\lib\quill\include\quill/core/SourceLocation.h(44): error C3861: '__builtin_LINE': identifier not found [D:\CLion Projects\Proj\build\deb\Proj.vcxproj]
D:\CLion Projects\Proj\lib\quill\include\quill/core/SourceLocation.h(43): error C3861: '__builtin_FUNCTION': identifier not found [D:\CLion Projects\Proj\build\deb\Proj.vcxproj]
D:\CLion Projects\Proj\lib\quill\include\quill/core/SourceLocation.h(42): error C3861: '__builtin_FILE': identifier not found [D:\CLion Projects\Proj\build\deb\Proj.vcxproj]
To Reproduce
Install MSVC
Set QUILL_X86ARCH to ON (using CMake as the build system)
Compile the project
Expected Behaviour No error
Environment Details
- Library Version: master
- Operating System: Windows 11
- Compiler: MSVC 19.16.27054.0
Additional context Add any other context about the problem here.
Hey, thanks for your report and the detailed information.
The macro-free mode depends on the compiler supporting std::source_location or compatible built-in functionality.
However, the errors you're seeing (__builtin_FILE, __builtin_FUNCTION, __builtin_LINE not found) happen because MSVC—especially the version you're using (19.16.27054.0, which is Visual Studio 2017)—does not provide these built-ins, nor does it have support for std::source_location until newer versions of MSVC.
MSVC does not have direct equivalents and only started supporting std::source_location in Visual Studio 2019 version 16.7 and above.
Unfortunately, this means that with your current MSVC version, it isn't possible to use the macro-free feature as those identifier macros are simply unavailable.
You'll need a more recent MSVC version (VS2019 16.7+) for std::source_location, or else stick with macro-assisted logging on older compilers.
If I'm not mistaken these are gcc builtins Could they be changed to something else if the compiler is an older MSVC?
I'm not aware of a direct equivalent to __builtin_FILE, __builtin_FUNCTION, or __builtin_LINE for older MSVC compilers. These builtins were introduced to provide specific functionality that older MSVC versions don’t support.
Before these builtins existed, the usual workaround was to pass the location information explicitly using macros, like the traditional logging macros
For older compilers when LogFunctions are used, the only practical workaround I can think of is to omit this information entirely (e.g., print an empty string "" instead).
If you know a better alternative or workaround for older MSVC versions, feel free to share
Old MSVC (no built‑ins):
- You only have the preprocessor macros FILE, FUNCTION, LINE.
- To capture the caller’s location, you must write your own macro wrapper and pass those macros in.
- If you wrap them in a normal function, they resolve to the place inside that function, not your call site.
New MSVC (with built‑ins):
- You get __builtin_FILE(), __builtin_FUNCTION(), __builtin_LINE() as real compiler intrinsics.
- They always reflect the immediate caller’s context, even when called inside helper functions.
- Libraries like std::source_location can now work without any user‐visible macros.
You can experiment with this simple example demonstrating a minimal SourceLocation type using __builtin_FUNCTION and try to replace __builtin_FUNCTION in older MSVC versions. I couldn't find a direct equivalent
#include <iostream>
struct SourceLocation {
constexpr SourceLocation(const char* f) : func(f) {}
static constexpr SourceLocation current(
const char* func_name = __builtin_FUNCTION())
{
return SourceLocation(func_name);
}
const char* func;
};
const char* foo(SourceLocation sl = SourceLocation::current()) {
return sl.func;
}
void user_code() {
std::cout << "foo was called by: " << foo() << "\n";
}
int main() {
user_code();
}
If you know a better alternative or workaround for older MSVC versions, feel free to share
If there are implementations of said intrinsics, maybe doing something like:
#if _MSC_VER <= /*Whatever 2017's versioning is
#define __builtin_FILE Impl_FILE()
#define __builtin_FUNCTION Impl_FUNCTION()
#define __builtin_LINE Impl_LINE()
#endif