SAL 中 _Out_writes_ 和 _Out_writes_all_ 的区别
经常写 Windows 程序的人一定不会对 SAL 陌生。SAL(Source Annotation Language)可以帮助你在编译的时候就检测出一些可能的运行时错误,比如数组越界。不是很了解? >阿硬文档传送门<
之前一直没有留意有些参数的 Annotation 后附带的 _all_
的含义,比如 _Out_writes_all_(s)
。什么时候该用这个,什么时候又该用不带 _all_
的 _Out_writes_(s)
呢?
_Out_writes_(s)
表示传入数组可以写入的有效长度是 s
,并且这个函数会往这个参数内写入一些东西,但是现在并不知道具体会写入多长的数据。比如 strcpy
就适用这种情况:虽然肯定知道 dest
会被从 src
中复制过来一段数据,但是多长…起码这个长度没有一个现成的变量可以指明。以下是阿硬文档中的栗子🌰:
1 | typedef _Null_terminated_ wchar_t *PWSTR; |
_Out_writes_all_(s)
则说明除了数组可以写入的有效长度是 s
,也保证调用后整个数组都是有效的,这实际上等效于写 _Out_writes_to_(s, s)
。适用的情况有 memset
,因为 memset 一定会把整个数组全部填充满。以下是 memset
在 MSVC 里的声明:
1 | void* __cdecl memset( |
个人认为 SAL 还是相当强大好用的,苦于文档太少只能自己摸索使用姿势和 best practise,(当然上述内容还是有在文档记录的…)希望阿硬赶紧能把 SAL 的文档写完善一些((
SAL 中 _Out_writes_ 和 _Out_writes_all_ 的区别
https://kernelbin.cn/2023/09/11/difference-between-out-writes-and-out-writes-all/