在运行时检查指针后面的数据以避免段错误:(wchar_t *) 与 (char *)

Checking data behind pointer at runtime to avoid segfaults : (wchar_t *) vs. (char *)

我有一个类似 printf 的函数,可以处理 %s (char *) 和 %ls (wchar_t *) 转换。如果我为正确的 conv 说明符传递正确的参数,一切正常。

但是如果我在函数需要 wchar_t * 时将 char * 传递给它,它可能会出现段错误(空终止字节位于 wchar_t 的第二个字节实例)。由于我通过 va_arg() 访问此参数,因此我无法确定类型。

如果我认为这个 char 数组总是以 NUL 结尾,我可以逐字节检查以正确处理以 NUL 结尾的字符并在它之后停止内存访问。但是这样我就无法处理 wchar_t 这样的合法值:

0b XXXXXXXX XXXXXXXX 00000000 XXXXXXXX

我已经在使用 __attribute__ printf GNU C 扩展。但是我这个函数可能被 python 程序通过 ctypes 使用,所以 format/type 在编译时检查可能还不够。

有没有办法在我的 C 函数中在运行时执行此类检查?

(NB : "There is no such way" 可能是答案,但我仍然在询问以确保完全确定。)

不,这不可能。

在典型的 C 实现中,类型系统仅作为编译时的辅助工具存在。*在运行时,您所拥有的只是数据字节,甚至没有办法从数字中区分指针(除了受过教育的猜测)。

从技术上讲,如果原始参数不是 char*signed char*unsigned char* 或 [=,您甚至不允许 va_arg(ap, const char*) 然后检查内存14=],或此类类型的 const 相关版本。传递给 va_arg 的类型始终需要是兼容类型。 (一个原因是不能保证指向不同类型的指针具有相同的大小、布局和含义。)

(*在 C++ 中,这个故事有点多,因为表示类型的数据存储时连接到多态对象以使 dynamic_casttypeid 正常工作,并与所有异常对象相关联以使 catch 块正常工作。但是 none 与 va_arg 兼容。)