保留参数的概念和使用场景

什么是保留参数(reserved parameter)

某些 API 函数的部分参数要求调用者必须传入指定的固定值,且这些参数名中通常带 reserved 字样。一般来说,调用者不遵守此约定会导致调用失败。

例如,Windows API 中的:

LONG WINAPI RegQueryValueEx(
  __in         HKEY hKey,
  __in_opt     LPCTSTR lpValueName,
  __reserved   LPDWORD lpReserved,
  __out_opt    LPDWORD lpType,
  __out_opt    LPBYTE lpData,
  __inout_opt  LPDWORD lpcbData
);

这里的 lpReserved 必须传 NULL,不然调用失败。

为什么要有保留参数

主要原因有两个。

一是方便扩展,且扩展不改变 ABI。如果没有保留参数,那么扩展函数功能必须另外取名(提供一个新函数),例如 accept2accept3accept4 这样很丑的名字。

二是供内部调用使用。例如,用户态程序调用必须传指定值,而系统内部可以使用这个值达成某种目的。

还有一种说法是这个参数之前有用,现已废弃。我认为可能性不大,如果要求废弃的参数必须传指定值,那么旧程序就会失效。

什么时候设计保留参数

需要 ABI 长期兼容且有比较大概率需要扩展的场景可以考虑使用保留参数。

反之,不需要 ABI 兼容的场景或已经确定无扩展需要的场景不应使用保留参数。用了反而给调用者和库作者带来不必要的干扰。

以下情况不应使用保留参数:

  • HTTP API,增加参数之后客户端不用修改,只要在服务端处理默认值。
  • 私有库,需要扩展时,双方都改。
  • 参数已彻底设计好。
  • 短期产品或项目。

怎样设计保留参数

(1)切勿滥用。

(2)保留参数一般放在最后一个。

(3)保留参数的类型要适应尽可能多的情况。例如,C 语言库的保留参数类型一般为 void*,将来可以改成任何指针类型。

posted @ 2022-11-01 19:47  风华神使  阅读(179)  评论(0)    收藏  举报