如果我正在使用当前使用特定数字类型别名的库,例如
typedef uint32_t library_type;
void library_function(library_type x);
即使库更改了typedef,我如何确保需要传递来自其他类型的值的代码仍然正确?
uint64_t x = get_some_number();
// …need checks here…
library_function((library_type)x);
我可以添加以下检查:
assert(sizeof library_type >= sizeof uint32_t);
assert(x <= UINT32_MAX);
第二次检查将确保我得到的值适合在current library_type
的范围内。库作者未提供LIBRARY_TYPE_MAX
定义,因此,如果将来在编译代码时出于任何原因更改library_type
时,第一个检查尝试保护第二个检查。
如果library_type
更改为例如int8_t
,但是如果将library_type
改为int32_t
怎么办?它仍然是正确的“大小”,但范围仍然小于我正在检查的范围!
C语言是否提供一种操作符,可以以sizeof
让我知道宽度的方式对类型的符号进行内省?还有其他方法可以确保仅在正确的情况下才可以强制转换为library_type
吗?
即使库更改了typedef,我如何确保需要传递来自其他类型的值的代码仍然正确?
您要防御的情况是不负责任的人类行为]中的一种,而不是技术性的一种。
在API中更改参数的类型定义是“重大更改”,就像其他任何行为更改一样。如果不仅仅是一个错误修正,那么这样的更改也可能暗示了其他更改,这些更改可能更加微妙和严重。
重大更改应记录在发行说明中。
[通常,如果在API中自动执行重大更改,则可以通过版本标识符或功能查询之类的方法在构建和/或运行时进行检查-库标头中的某个位置为#define LIBRARY_WHATEVER_VERSION 3
,那么您的代码可以具有预处理器指令来进行检查。
当重大更改确实很严重时,通常会重命名软件本身,以使错误的版本甚至无法满足#include或链接尝试。
是的,关系运算符与强制转换运算符组合。例如: