strtok_s 和编译器 C11 向前兼容

LuC*_*LuC 4 c gcc msvcrt visual-studio mingw-w64

C11 中的声明strtok_s及其用法看起来与 Visual Studio 2022 (17.4.4) 和 GCC 12.2.0 捆绑的最新编译器(查看 MinGW64 发行版)中的in 编译器非常不同。strtok_s

我担心这种不同的形式早在 C11 之前就已被开发为更安全且被接受的替代品strtok。如果有人想要使用strtok_s并保持 C11 合规,现在会发生什么?

编译器提供的库是否兼容 C11?

也许只是我被一些显而易见的事情愚弄了,有人可以帮助我......


这是 C11(与 C17 和 C23 的早期草案类似):

char *strtok_s(char * restrict s1,
    rsize_t * restrict s1max,
    const char * restrict s2,
    char ** restrict ptr);
Run Code Online (Sandbox Code Playgroud)

同样可以在safec 库中找到一个很好的参考

MSC/VC和 GCC 的形式为

char* strtok_s(
    char* str,
    const char* delimiters,
    char** context
);
Run Code Online (Sandbox Code Playgroud)

Lun*_*din 6

C11“Annex K 边界检查接口”受到了很多怀疑,实际上几乎没有标准库实现它。例如,请参阅附件 K \xe2\x80\x94 边界检查接口的现场经验

\n

至于 MSVC 编译器,它不符合任何 C 标准,也从未做出过这样的声明 - 你可以尝试一下,检查你是否正在使用这样的编译器:

\n
#if !defined(__STDC__) || (__STDC__==0)\n  #error This compiler is non-conforming.\n#endif\n
Run Code Online (Sandbox Code Playgroud)\n

特别是,MSVC 也没有实现附件 K,但在 C11 之前就已经有了非标准库扩展。

\n

在实践中_s意味着:

\n
    \n
  • 可能更安全,也可能更不安全,具体取决于用途和程序员的期望。
  • \n
  • 不可携带。
  • \n
  • 可能不符合规定。
  • \n
\n

如果可移植性和标准一致性很重要,那么就避免使用_s函数。

\n

在实践中_s,函数可以防止两件事:传递未经净化的输入或空指针。因此,假设您进行了适当的输入清理并且不将空指针传递给库函数,则这些_s函数不会为您提供额外的安全性,而只会带来额外的执行膨胀和可移植性问题。

\n