[libcxx-commits] [libcxx] [libc++] Optimize std::print for Windows 8+ (PR #232993)
Yexuan Xiao via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Oct 21 22:02:44 PDT 2026
https://github.com/YexuanXiao updated https://github.com/llvm/llvm-project/pull/232993
>From 4eb0e80b623cbc4e2e719a53a1fbbdd47c2fe446 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Sat, 17 Oct 2026 08:52:42 +0800
Subject: [PATCH 1/7] Optimize std::print for Windows 8+
---
libcxx/src/print.cpp | 38 ++++++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index 2eb8a0f31488c..c93a484188888 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -19,7 +19,10 @@
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <io.h>
+# include <versionhelpers.h>
# include <windows.h>
+# include <winioctl.h>
+# include <winternl.h>
#elif __has_include(<unistd.h>)
# include <unistd.h>
# if defined(_NEWLIB_VERSION)
@@ -36,19 +39,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
#ifdef _WIN32
+// Exported by ntdll.lib and can most efficiently query whether a HANDLE references a console.
+// Since the user mode header isn't provided, all needed declarations are declared manually.
+extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryVolumeInformationFile(
+ HANDLE handle, PIO_STATUS_BLOCK ioStatus, PVOID information, ULONG length, ULONG informationClass);
-_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) {
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_file_fs_device_information
+struct FILE_FS_DEVICE_INFORMATION {
+ DEVICE_TYPE DeviceType;
+ ULONG Characteristics;
+};
+
+// https://learn.microsoft.com/en-us/windows/console/console-handles
+static bool __is_handle_terminal_win8_or_greater(HANDLE handle) {
+ // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_fsinfoclass
+ constexpr ULONG FileFsDeviceInformation = 4;
+ IO_STATUS_BLOCK iosb;
+ FILE_FS_DEVICE_INFORMATION info;
+ const auto status = NtQueryVolumeInformationFile(handle, &iosb, &info, sizeof(info), FileFsDeviceInformation);
+ return (status >= 0) && (info.DeviceType == FILE_DEVICE_CONSOLE);
+}
+
+static bool __is_handle_terminal(HANDLE handle) {
// Note the Standard does this in one call, but it's unclear whether
// an invalid handle is allowed when calling GetConsoleMode.
- //
- // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
// https://learn.microsoft.com/en-us/windows/console/getconsolemode
+ unsigned long __mode;
+ return GetConsoleMode(reinterpret_cast<void*>(__handle), &__mode);
+}
+
+_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) {
+ // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170
intptr_t __handle = _get_osfhandle(fileno(__stream));
if (__handle == -1)
return false;
-
- unsigned long __mode;
- return GetConsoleMode(reinterpret_cast<void*>(__handle), &__mode);
+ static bool __win8_or_greater = IsWindows8OrGreater();
+ return __win8_or_greater ? __is_handle_terminal_win8_or_greater(__handle) : __is_handle_terminal(__handle);
}
# if _LIBCPP_HAS_WIDE_CHARACTERS
>From b470104af09770e24ee425b46fbfa961979c9494 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Sat, 17 Oct 2026 11:40:44 +0800
Subject: [PATCH 2/7] Fix viriable names
---
libcxx/src/print.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index c93a484188888..dc9640316ff82 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -51,16 +51,16 @@ struct FILE_FS_DEVICE_INFORMATION {
};
// https://learn.microsoft.com/en-us/windows/console/console-handles
-static bool __is_handle_terminal_win8_or_greater(HANDLE handle) {
+static bool __is_handle_terminal_win8_or_greater(HANDLE __handle) {
// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_fsinfoclass
constexpr ULONG FileFsDeviceInformation = 4;
IO_STATUS_BLOCK iosb;
FILE_FS_DEVICE_INFORMATION info;
- const auto status = NtQueryVolumeInformationFile(handle, &iosb, &info, sizeof(info), FileFsDeviceInformation);
+ const auto status = NtQueryVolumeInformationFile(__handle, &iosb, &info, sizeof(info), FileFsDeviceInformation);
return (status >= 0) && (info.DeviceType == FILE_DEVICE_CONSOLE);
}
-static bool __is_handle_terminal(HANDLE handle) {
+static bool __is_handle_terminal(HANDLE __handle) {
// Note the Standard does this in one call, but it's unclear whether
// an invalid handle is allowed when calling GetConsoleMode.
// https://learn.microsoft.com/en-us/windows/console/getconsolemode
>From 0096249d44580618ad103c7e214b4f562b352e27 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Sat, 17 Oct 2026 11:45:10 +0800
Subject: [PATCH 3/7] Underscore the variable name
---
libcxx/src/print.cpp | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index dc9640316ff82..e89effcc069a4 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -50,14 +50,16 @@ struct FILE_FS_DEVICE_INFORMATION {
ULONG Characteristics;
};
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_fsinfoclass
+# define FileFsDeviceInformation 4
+
// https://learn.microsoft.com/en-us/windows/console/console-handles
static bool __is_handle_terminal_win8_or_greater(HANDLE __handle) {
- // https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_fsinfoclass
- constexpr ULONG FileFsDeviceInformation = 4;
- IO_STATUS_BLOCK iosb;
- FILE_FS_DEVICE_INFORMATION info;
- const auto status = NtQueryVolumeInformationFile(__handle, &iosb, &info, sizeof(info), FileFsDeviceInformation);
- return (status >= 0) && (info.DeviceType == FILE_DEVICE_CONSOLE);
+ IO_STATUS_BLOCK __iosb;
+ FILE_FS_DEVICE_INFORMATION __info;
+ const auto __status =
+ NtQueryVolumeInformationFile(__handle, &__iosb, &__info, sizeof(__info), FileFsDeviceInformation);
+ return (__status >= 0) && (info.DeviceType == FILE_DEVICE_CONSOLE);
}
static bool __is_handle_terminal(HANDLE __handle) {
>From 5b9e7cb9f5c5096b14d7740459c9053e7bd6b5da Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Sat, 17 Oct 2026 14:11:40 +0800
Subject: [PATCH 4/7] Fix type missmatch
---
libcxx/src/print.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index e89effcc069a4..4fc733e74ad34 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -54,15 +54,15 @@ struct FILE_FS_DEVICE_INFORMATION {
# define FileFsDeviceInformation 4
// https://learn.microsoft.com/en-us/windows/console/console-handles
-static bool __is_handle_terminal_win8_or_greater(HANDLE __handle) {
+static bool __is_handle_terminal_win8_or_greater(intptr_t __handle) {
IO_STATUS_BLOCK __iosb;
FILE_FS_DEVICE_INFORMATION __info;
- const auto __status =
- NtQueryVolumeInformationFile(__handle, &__iosb, &__info, sizeof(__info), FileFsDeviceInformation);
+ const auto __status = NtQueryVolumeInformationFile(
+ reinterpret_cast<void*>(__handle), &__iosb, &__info, sizeof(__info), FileFsDeviceInformation);
return (__status >= 0) && (info.DeviceType == FILE_DEVICE_CONSOLE);
}
-static bool __is_handle_terminal(HANDLE __handle) {
+static bool __is_handle_terminal(intptr_t __handle) {
// Note the Standard does this in one call, but it's unclear whether
// an invalid handle is allowed when calling GetConsoleMode.
// https://learn.microsoft.com/en-us/windows/console/getconsolemode
>From 04ab02ca9541c00a4e8af79bcd4823ee81d46fb1 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Sat, 17 Oct 2026 15:06:58 +0800
Subject: [PATCH 5/7] Fix a viriable name
---
libcxx/src/print.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index 4fc733e74ad34..d565f2554049f 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -59,7 +59,7 @@ static bool __is_handle_terminal_win8_or_greater(intptr_t __handle) {
FILE_FS_DEVICE_INFORMATION __info;
const auto __status = NtQueryVolumeInformationFile(
reinterpret_cast<void*>(__handle), &__iosb, &__info, sizeof(__info), FileFsDeviceInformation);
- return (__status >= 0) && (info.DeviceType == FILE_DEVICE_CONSOLE);
+ return (__status >= 0) && (__info.DeviceType == FILE_DEVICE_CONSOLE);
}
static bool __is_handle_terminal(intptr_t __handle) {
>From 3c7d82f337a46deb5fba28f2cb6e57af9dcb7ee6 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Thu, 22 Oct 2026 12:54:26 +0800
Subject: [PATCH 6/7] Dynamically load ntdll.dll instead of linking ntdll.lib
---
libcxx/src/print.cpp | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index d565f2554049f..338e29d1701ce 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -39,10 +39,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
_LIBCPP_BEGIN_EXPLICIT_ABI_ANNOTATIONS
#ifdef _WIN32
-// Exported by ntdll.lib and can most efficiently query whether a HANDLE references a console.
-// Since the user mode header isn't provided, all needed declarations are declared manually.
-extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryVolumeInformationFile(
- HANDLE handle, PIO_STATUS_BLOCK ioStatus, PVOID information, ULONG length, ULONG informationClass);
+
+using NtQueryVolumeInformationFileType = NTSTATUS
+ NTAPI(HANDLE handle, PIO_STATUS_BLOCK ioStatus, PVOID information, ULONG length, ULONG informationClass);
// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_file_fs_device_information
struct FILE_FS_DEVICE_INFORMATION {
@@ -53,12 +52,22 @@ struct FILE_FS_DEVICE_INFORMATION {
// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_fsinfoclass
# define FileFsDeviceInformation 4
+static NtQueryVolumeInformationFileType* __get_NtQVIF_win8_or_greater() {
+ // Windows 7 does not support querying the device type of a console handle, so returning nullptr indicates that this
+ // approach is not supported.
+ if (!IsWindows8OrGreater())
+ return nullptr;
+ return (NtQueryVolumeInformationFileType*)GetProcAddress(
+ GetModuleHandleW(L"ntdll.dll"), "NtQueryVolumeInformationFile");
+}
+
// https://learn.microsoft.com/en-us/windows/console/console-handles
-static bool __is_handle_terminal_win8_or_greater(intptr_t __handle) {
+// Exported by ntdll and can most efficiently query whether a HANDLE references a console.
+static bool __is_handle_terminal_win8_or_greater(NtQueryVolumeInformationFileType* __fp, intptr_t __handle) {
IO_STATUS_BLOCK __iosb;
FILE_FS_DEVICE_INFORMATION __info;
- const auto __status = NtQueryVolumeInformationFile(
- reinterpret_cast<void*>(__handle), &__iosb, &__info, sizeof(__info), FileFsDeviceInformation);
+ const auto __status =
+ __fp(reinterpret_cast<void*>(__handle), &__iosb, &__info, sizeof(__info), FileFsDeviceInformation);
return (__status >= 0) && (__info.DeviceType == FILE_DEVICE_CONSOLE);
}
@@ -75,8 +84,8 @@ _LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) {
intptr_t __handle = _get_osfhandle(fileno(__stream));
if (__handle == -1)
return false;
- static bool __win8_or_greater = IsWindows8OrGreater();
- return __win8_or_greater ? __is_handle_terminal_win8_or_greater(__handle) : __is_handle_terminal(__handle);
+ static auto __fp = __get_NtQVIF_win8_or_greater();
+ return __fp ? __is_handle_terminal_win8_or_greater(__fp, __handle) : __is_handle_terminal(__handle);
}
# if _LIBCPP_HAS_WIDE_CHARACTERS
>From b5c95fbb7b585362108a10569ac197f96f4f879f Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Thu, 22 Oct 2026 13:02:23 +0800
Subject: [PATCH 7/7] Check if the call succeeds with NT_SUCCESS
---
libcxx/src/print.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/src/print.cpp b/libcxx/src/print.cpp
index 338e29d1701ce..a922136140936 100644
--- a/libcxx/src/print.cpp
+++ b/libcxx/src/print.cpp
@@ -68,7 +68,7 @@ static bool __is_handle_terminal_win8_or_greater(NtQueryVolumeInformationFileTyp
FILE_FS_DEVICE_INFORMATION __info;
const auto __status =
__fp(reinterpret_cast<void*>(__handle), &__iosb, &__info, sizeof(__info), FileFsDeviceInformation);
- return (__status >= 0) && (__info.DeviceType == FILE_DEVICE_CONSOLE);
+ return NT_SUCCESS(__status) && (__info.DeviceType == FILE_DEVICE_CONSOLE);
}
static bool __is_handle_terminal(intptr_t __handle) {
More information about the libcxx-commits
mailing list