亟需MSVC中_doserrno全局变量的详细说明
_doserrno Global Variable I totally get your frustration with the lack of clear documentation around _doserrno—it's one of those MSVC-specific CRT extensions that feels under-documented compared to standard errno. Let's break down your questions with practical insights based on CRT behavior and implementation:
Which functions set _doserrno?
MSVC doesn't explicitly list all functions that set _doserrno, but from practical use and looking at CRT source code, it's primarily set by C standard library functions that interact directly with the Windows OS via Win32 APIs. Key examples include:
- File I/O functions:
fopen,_open,fread,fwrite,_unlink,_rename,_fseek(when seeking fails due to system-level issues) - Directory operations:
_mkdir,_rmdir,_chdir - Console I/O functions:
printf,scanf,getchar(only when the underlying console read/write fails, not for formatting errors) - Process execution functions:
_execfamily,_spawnfamily (when process creation fails at the system level)
Important note: Not every error from these functions will set _doserrno—only errors that originate from a failed Win32 API call. Purely C-standard errors (like passing an invalid file pointer to fread) won't touch _doserrno, only errno.
Is _doserrno always a Win32 error code?
Your hunch is correct! In MSVC's CRT implementation, _doserrno is explicitly used to store the Win32 error code returned by GetLastError() when a C library function calls a Win32 API that fails. The CRT then maps this Win32 code to a standard errno value (e.g., ERROR_FILE_NOT_FOUND becomes ENOENT). This mapping is consistent across all MSVC versions, so whenever _doserrno is set by a CRT function, it will be a valid Win32 error code.
How to convert _doserrno to a string without using Win32's FormatMessage()?
You're right that calling FormatMessage() directly bypasses the CRT's intended design for _doserrno. Instead, use these MSVC-CRT-specific functions that handle _doserrno natively:
_strerror_dos(MSVC-only)
This function is purpose-built to convert a_doserrnovalue to a human-readable string. It's part of the CRT, so it aligns with the C API context:char error_buffer[512]; _strerror_dos(error_buffer, sizeof(error_buffer), _doserrno); fprintf(stderr, "System error details: %s\n", error_buffer);_perroror_strerror
While these functions focus onerrno, they will automatically incorporate_doserrnodetails when the error is system-level. For example:// If errno was set due to a Win32 API failure, _perror will include _doserrno's message _perror("Operation failed");
These methods keep you within the CRT ecosystem, avoiding direct Win32 API calls while still getting meaningful error strings from _doserrno.
内容的提问来源于stack exchange,提问作者MuldeR

