比较有意思的几个地方
模板结构体内无名enum可以继承于bool,限定了枚举值范围。
enum : bool { __the_value = false };
结构体内可以直接定义一个static_assert,调用时比仿函数少一次()
关于_STRINGIZE之类的宏要拐个弯定义的原因如下:
#define _STRINGIZEX(x) #x
#define _STRINGIZE(x) _STRINGIZEX(x) //转字符串
#define _stringize_test(x) #x
int x = 42;
const char* str1 = _stringize_test(x);//"x"
const char* str2 = _STRINGIZE(x);//"42" "x" 与编译器也有关系
//指定函数调用约定:通过__declspec(calltype)可以指定函数使用的调用约定,如__stdcall、__cdecl、__fastcall等。
//__stdcall 一种函数调用规约,函数的参数是从右往左依次压入栈中,由被调用函数来负责栈平衡,EAX 返回值,常用于Win32 API 中。
//__cdecl 也是一种标准的调用规约,由调用者负责栈平衡,即在函数返回前,调用者需要弹出栈上的参数。常用于 C 语言标准库函数中。
//__fastcall 是一种优化的调用规约,函数的参数尽可能地放入寄存器中,从而减少了栈上的数据传输和栈平衡的开销,提高了函数的执行效率。__fastcall 调用约定通常用于对执行效率有严格要求的程序中。
// Definitions of common __declspecs Microsoft C/C++编译器扩展
#define _VCRT_NOALIAS __declspec(noalias) //指针参数不会指向任何其他变量或对象
#define _VCRT_RESTRICT __declspec(restrict) //指定指针所指向的内存区域是独立的,即没有别的指针指向同一块内存区域。
//导出函数和变量:通过__declspec(dllexport)可以将函数和变量标记为在DLL中可用,以便其他模块可以访问它们。
//引用导入函数和变量:通过__declspec(dllimport)可以在程序中引用另一个模块中的导出函数和变量。
//指定内存分配方式:通过__declspec(align(n))可以指定变量在内存中的对齐方式,以提高访问效率。
//指定函数调用方式:通过__declspec(naked)可以指定函数以汇编代码的形式实现,以提高执行效率。
//指定函数调用约定:通过__declspec(calltype)可以指定函数使用的调用约定,如__stdcall、__cdecl、__fastcall等。
//__declspec(allocate("segname")) int i = 0;控制变量被分配在哪个数据段code_seg,const_seg,data_seg,init_seg,section
//__declspec(deprecated(MY_TEXT)) void func(int) {} 提醒c4996警告
//__declspec(jitintrinsic)标记一个函数或元素为64位公共语言运行时
//__declspec(restrict) float* init(int m, int n) {}; 指针所指向的内存区域是独立的
//__declspec(noalias) void multiply(float* a, float* b, float* c) {}; 指针参数不会指向任何其他变量或对象
//__declspec(noinline) int mbrfunc() { return 0; /* will not inline*/ };不内联
//__declspec(noreturn) extern void fatal () {}不需要返回值。
//void __declspec(nothrow) __stdcall f2();不存在异常抛出。
//struct __declspec(novtable) X { virtual void mf(); };标记的类或结构不能直接实例化,否则将引发AV错误(access violation)。
// __declspec(property(get = getprop, put = putprop)) int the_prop;};定义实现针对一个字段的可读或可写
//__declspec(selectany) type class::variable = value; 模板编程时,在h文件初始化一个全局变量
//__declspec(thread) int in_One_Thread; 线程局部变量并具有线程存储时限
//struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown; 将具有唯一表示符号的已注册内容声明为一个变量,可使用__uuidof()调用。
//Microsoft Source Code Annotation Language SAL微软的源代码注释语言
// #include 头文件注释
//
// Note on use of "deprecate":使用“弃用”的注意事项:
// Various places in this header and other headers use
// __declspec(deprecate) or macros that have the term DEPRECATE in them.
// We use "deprecate" here ONLY to signal the compiler to emit a warning
// about these items. The use of "deprecate" should NOT be taken to imply
// that any standard committee has deprecated these functions from the
// relevant standards. In fact, these functions are NOT deprecated from
// the standard.
//此标头和其他标头中的多个位置使用 __declspec(deprecate)或其中包含术语 DEPRECATE 的宏。
//我们在这里使用“弃用”只是为了向编译器发出关于这些项目的警告。
//使用“弃用”不应被视为暗示任何标准委员会已从相关标准中弃用这些功能。 事实上,这些功能并没有从标准中弃用。
// Full details can be found in our documentation by searching for "Security Enhancements in the CRT".
//可以通过搜索在我们的文档中找到完整的详细信息“CRT 中的安全增强”。
#ifndef _VCRT_COMPILER_PREPROCESSOR
// Many VCRuntime headers avoid exposing their contents to non-compilers like the Windows resource compiler and Qt's meta-object compiler (moc).
//许多 VCRuntime 标头避免将其内容暴露给非编译器,如 Windows 资源编译器和 Qt 的元对象编译器 (moc)。
#if defined(RC_INVOKED) || defined(Q_MOC_RUN)
#define _VCRT_COMPILER_PREPROCESSOR 0
#else
#define _VCRT_COMPILER_PREPROCESSOR 1
#endif
#endif // _VCRT_COMPILER_PREPROCESSOR
#ifndef _UCRT
#define _UCRT
#endif
// The _CRTIMP macro is not used in the VCRuntime or the CoreCRT anymore, but there is a lot of existing code that declares CRT functions using this macro, and if we remove its definition, we break that existing code. It is thus defined here only for compatibility.
//_CRTIMP 宏不再在 VCRuntime 或 CoreCRT 中使用,但有很多现有代码使用此宏声明 CRT 函数,如果我们删除它的定义,就会破坏现有代码。 因此在这里定义它只是为了兼容性。
#ifndef _CRTIMP
#define _VCRT_DEFINED_CRTIMP
#if defined CRTDLL && defined _CRTBLD
#define _CRTIMP __declspec(dllexport)
#else
#ifdef _DLL
#define _CRTIMP __declspec(dllimport)
#else
#define _CRTIMP
#endif
#endif
#endif
#include
#include
#pragma warning(push)
#pragma warning(disable: _VCRUNTIME_DISABLED_WARNINGS) //临时禁止部分编译告警
// All C headers have a common prologue and epilogue, to enclose the header in an extern "C" declaration when the header is #included in a C++ translation unit and to push/pop the packing.
//所有 C 标头都有一个共同的序言和结语,当标头被 #included 在 C++ 翻译单元中时,将标头包含在 extern "C" 声明中,并推入/弹出包装。
#if defined __cplusplus
#define _CRT_BEGIN_C_HEADER __pragma(pack(push, _CRT_PACKING)) extern "C" {
#define _CRT_END_C_HEADER } __pragma(pack(pop))
#elif defined __midl //接口定义语言相关的编译器 MIDL 编译器
...
#endif
#ifndef _HAS_EXCEPTIONS // Predefine as 0 to disable exceptions 预定义为 0 以禁用异常
#ifdef _KERNEL_MODE //核模式禁用异常(否则会异常调异常导致死循环)
#define _HAS_EXCEPTIONS 0
#else
#define _HAS_EXCEPTIONS 1
#endif /* _KERNEL_MODE */
#endif /* _HAS_EXCEPTIONS */
#define _CRT_STRINGIZE_(x) #x //转字符串
#define _CRT_STRINGIZE(x) _CRT_STRINGIZE_(x)
#define _CRT_WIDE_(s) L ## s //宽字符串
#define _CRT_WIDE(s) _CRT_WIDE_(s)
#define _CRT_CONCATENATE_(a, b) a ## b //连接字符串
#define _CRT_CONCATENATE(a, b) _CRT_CONCATENATE_(a, b)
#define _CRT_UNPARENTHESIZE_(...) __VA_ARGS__ //变参
#define _CRT_UNPARENTHESIZE(...) _CRT_UNPARENTHESIZE_ __VA_ARGS__
#ifndef _VCRTIMP //C run time implement,C运行库的实现, 运行时控制用动态链接库 还是静态链接
#define _VCRTIMP __declspec(dllexport)
#ifndef _MRTIMP //"Microsoft Runtime"
#define _MRTIMP __declspec(dllexport)
// Definitions of calling conventions used code sometimes compiled as managed
//调用约定的定义使用有时编译为托管的代码
#define __CLRCALL_OR_CDECL __clrcall //用于C++/CLI托管代码的调用修饰符
#define __CLRCALL_OR_CDECL __cdecl //非托管代码的调用约定,标准的C/C++调用约定,按照从右到左的顺序将参数压入堆栈中,并由调用方负责清理堆栈。
#ifdef _M_CEE_PURE
#define __CLRCALL_PURE_OR_CDECL __clrcall
#else
#define __CLRCALL_PURE_OR_CDECL __cdecl
#endif
#define __CRTDECL __CLRCALL_PURE_OR_CDECL
// For backwards compatibility
#define _WConst_return _CONST_RETURN
// Definitions of common types 类型定义
#ifdef _WIN64
typedef unsigned __int64 size_t;
typedef __int64 ptrdiff_t;
typedef __int64 intptr_t;
#else
typedef unsigned int size_t;
typedef int ptrdiff_t;
typedef int intptr_t;
#endif
// Indicate that these common types are defined 表示定义了这些公共类型
#define _SIZE_T_DEFINED
#define _PTRDIFF_T_DEFINED
#define _INTPTR_T_DEFINED
//不同编译器下bool类型的定义
#if defined __cplusplus
typedef bool __vcrt_bool;
#elif defined __midl
typedef char __vcrt_bool;
#else
typedef _Bool __vcrt_bool;
#endif
typedef unsigned short wchar_t;
#define _WCHAR_T_DEFINED
#define NULL 0 //__cplusplus
#define NULL ((void *)0)
#define _UNALIGNED __unaligned //不需要按照特定的字节对齐方式来存储在内存中
#if defined _M_ARM64EC
#define __security_check_cookie __security_check_cookie_arm64ec
#endif
#ifdef __cplusplus
extern "C++"
{ //这个难看懂
template <typename _CountofType, size_t _SizeOfArray>
char(*__countof_helper(_UNALIGNED _CountofType(&_Array)[_SizeOfArray]))[_SizeOfArray];
#define __crt_countof(_Array) (sizeof(*__countof_helper(_Array)) + 0)
}
#else
#define __crt_countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) //计算数组大小
#endif
#if defined(_M_IX86) && defined(_CRT_LEGACY_X86_FLT_EXCEPTIONS) && !defined(_M_CEE_PURE)
#pragma comment(lib, "legacy_x86_flt_exceptions")
#endif
#ifdef __cplusplus
#if defined(_MSVC_LANG) && _MSVC_LANG > __cplusplus //编译器版本控制
#define _STL_LANG _MSVC_LANG
#else // ^^^ language mode is _MSVC_LANG / language mode is __cplusplus vvv
#define _STL_LANG __cplusplus
#endif // ^^^ language mode is larger of _MSVC_LANG and __cplusplus ^^^
#else // ^^^ determine compiler's C++ mode / no C++ support vvv
#define _STL_LANG 0L
#endif // ^^^ no C++ support ^^^
#if _STL_LANG > 201402L
#define _HAS_CXX17 1
#if _HAS_CXX17 && _STL_LANG > 201703L
#define _HAS_CXX20 1
#if _HAS_CXX20 && _STL_LANG > 202002L
#define _HAS_CXX23 1
#elif __has_cpp_attribute(nodiscard) >= 201603L // 如果函数或方法返回值没有被使用,则发出一个编译器警告或者错误。
#define _HAS_NODISCARD 1
#pragma push_macro("msvc")
#pragma push_macro("constexpr")
#undef msvc
#undef constexpr
// Determine if we should use [[msvc::constexpr]] to allow for "extended constexpr" in Visual C++.
//确定我们是否应该使用 [[msvc::constexpr]] 以允许在 Visual C++ 中使用“扩展的 constexpr”。
#ifndef _MSVC_CONSTEXPR
#ifdef _MSVC_CONSTEXPR_ATTRIBUTE
#define _MSVC_CONSTEXPR [[msvc::constexpr]]
#else
#define _MSVC_CONSTEXPR
#endif
#endif
#pragma pop_macro("constexpr")
#pragma pop_macro("msvc")
// See note on use of "deprecate" at the top of this file 废弃代码告警时用的宏
#define _CRT_DEPRECATE_TEXT(_Text) __declspec(deprecated(_Text))
#if !defined _M_CEE && !defined __midl
void __cdecl __security_init_cookie(void);
#if defined(_M_IX86)
void __fastcall __security_check_cookie(_In_ uintptr_t _StackCookie);
__declspec(noreturn) void __cdecl __report_gsfailure(void);
#elif defined(_M_ARM64EC)
void __cdecl __security_check_cookie_arm64ec(_In_ uintptr_t _StackCookie);
__declspec(noreturn) void __cdecl __report_gsfailure(_In_ uintptr_t _StackCookie);
#else
void __cdecl __security_check_cookie(_In_ uintptr_t _StackCookie);
__declspec(noreturn) void __cdecl __report_gsfailure(_In_ uintptr_t _StackCookie);
#endif
#endif
extern uintptr_t __security_cookie;
//malloc() 和 calloc() 函数都可以用来动态分配内存空间,其中 malloc() 函数只分配内存空间而不初始化,
//而 calloc() 函数则分配内存空间并初始化为 0。realloc() 函数用于重新分配已经分配的内存空间的大小,
#ifndef _VCRT_BUILD
#define __vcrt_malloc_normal(_Size) malloc(_Size)
#define __vcrt_calloc_normal(_Count, _Size) calloc(_Count, _Size)
#define __vcrt_free_normal(_Memory) free(_Memory)
#endif
#include // The _HAS_CXX tags must be defined before including this. 关键字检查,禁止用户乱用cpp关键字
#if defined(break) //示例,禁止乱用break定义宏
#define break EMIT WARNING C4005
#error The C++ Standard Library forbids macroizing the keyword "break". \
Enable warning C4005 to find the forbidden define.
#endif // break
//Microsoft Source Code Annotation Language 源代码注释语言
#include //sal.h 提供了一组注释来描述一个函数如何使用它的参数——它对它们所做的假设,以及它在完成时所做的保证。
// 使用的宏助手的定义。定义变参的解析方式。
#include
extern "C++"{
template <typename _Ty>
struct __vcrt_va_list_is_reference{//默认模板类
enum : bool { __the_value = false };//指明enum取值只能时bool类型,继承于bool
};
template <typename _Ty>
struct __vcrt_va_list_is_reference<_Ty&>{
enum : bool { __the_value = true };//偏特化版本,引用类型判断
};
template <typename _Ty>
struct __vcrt_va_list_is_reference<_Ty&&>{
enum : bool { __the_value = true };//偏特化版本,引用类型判断
};
template <typename _Ty>
struct __vcrt_assert_va_start_is_not_reference{ //编译器告警:va_start 参数不能有引用类型,也不能带括号
static_assert(!__vcrt_va_list_is_reference<_Ty>::__the_value,"va_start argument must not have reference type and must not be parenthesized");
};//__vcrt_assert_va_start_is_not_reference() 调用方式比仿函数少一次()
} // extern "C++"
//decltype(x)从表达式中推导出其类型。在 va_start 宏中添加参数类型检查的功能。
#define __crt_va_start(ap, x) ((void)(__vcrt_assert_va_start_is_not_reference<decltype(x)>(), __crt_va_start_a(ap, x)))