c# strtok_s和编译器C11向前兼容性

sirbozc5  于 2023-02-01  发布在  C#
关注(0)|答案(2)|浏览(227)

C11中strtok_s的声明及其用法看起来非常不同于编译器中的strtok_s,比如最新的Visual Studio 2022(17.4.4)和GCC 12.2.0(查看MinGW64发行版)。
我担心不同的形式早在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);

safec library中可以找到相同的良好参考
MSC/VC和GCC的格式为

char* strtok_s(
   char* str,
   const char* delimiters,
   char** context
);
f5emj3cl

f5emj3cl1#

C11“Annex K bounds checking interfaces”受到了很多质疑,实际上几乎没有标准库实现它,例如Field Experience With Annex K — Bounds Checking Interfaces
至于MSVC编译器,它不符合任何C标准,也从未做过这样的声明--你可以试试这个来检查你是否在使用这样的编译器:

#if !defined(__STDC__) || (__STDC__==0)
  #error This compiler is non-conforming.
#endif

特别是,MSVC也没有实现附录K,但是在C11之前已经有了非标准的库扩展。
实际上,_s表示:

  • 可能更安全或可能更不安全,取决于使用和程控仪预期。
  • 非便携式。
  • 可能不合格。

如果可移植性和标准一致性很重要,那么就避免使用_s函数。
在实践中,_s函数可以防止两种情况:所以假设你做了正确的输入清理并且没有给库函数传递空指针,_s函数并没有给你额外的安全性,只是额外的执行膨胀和可移植性问题。

ecbunoof

ecbunoof2#

如果有人想使用strtok_s并保持C11兼容性,现在会发生什么?
你 * 事实上*不能
它不仅限于strtok_s(),整个C11附录K的实现集都是分裂的,因为与标准的主要偏差来自微软的实现,可能永远不会有一种方法来编写可移植的,符合标准的代码使用附录K的函数。
根据N1967附录K现场经验-边界检查界面

可用的实现

尽管API的规范已经存在了十多年,但只有少数实现具有不同程度的完整性和一致性。以下是已知存在的实现及其状态的调查。
虽然下面的两个实现可以作为开源项目以可移植源代码的形式提供,没有一个流行的开源发行版,如BSD或Linux,选择让它们的用户可以使用其中的任何一个。(GNU C Library)曾多次拒绝包含的建议,其原因与Austin小组在其对TR 24731-1 N1106的初步审查中所指出的相同]。这些发行版的未来版本似乎不太可能提供这些API。

微软可视化工作室

Microsoft Visual Studio实现了API的早期版本。但是,该实现不完整,既不符合C11,也不符合原始TR 24731-1。例如,它不提供set_constraint_handler_s函数,而是定义了一个_invalid_parameter_handler _set_invalid_parameter_handler(_invalid_parameter_handler)函数,该函数具有类似的行为,但签名略有不同且不兼容。不要定义abort_handler_signore_handler_s函数、memset_s函数(不是TR的一部分)或RSIZE_MAX宏。Microsoft实现也不会将重叠的源序列和目标序列视为运行时约束冲突,而是在此类情况下具有未定义的行为。
由于与规范存在大量偏差,因此Microsoft实现不能被视为符合规范或可移植。
...

安全C库

Safe C Library [SafeC]是一个相当高效和可移植的附件K的实现,但不幸的是它非常不完整,支持<string.h>中声明的字符串操作函数子集。
由于缺乏对<string.h>函数以外的附录K设施的支持,因此不能将Safe C库视为符合标准的实现。
即使是安全C库也是不一致的。
这些功能是否“更安全”是有争议的。阅读整个文档。

不必要的使用

微软为了提高API的采用率而弃用标准函数,由此产生了一个普遍的谬误,即对标准函数的每次调用都必然是不安全的,应该被对“更安全”API的调用所取代。有安全意识的团队有时会天真地开始长达数月的项目,重写他们的工作代码并尽职尽责地替换所有“已弃用”的示例这不仅会导致不必要的混乱,增加在正确代码中注入新错误的风险,还会降低重写代码的效率。
另外,请阅读更新的N1969 Updated Field Experience With Annex K — Bounds Checking Interfaces
尽管最初的提议已经提出了十多年,ISO/IEC TR 24731-1:2007已经批准了近十年,边界检查接口引入C标准也已经有近五年了,还没有出现可行的符合标准的实现。API仍然存在争议,实现请求仍然被实现者拒绝。
边界检查接口的设计虽然初衷良好,但存在太多问题需要纠正。与依赖现有方法或现代技术相比,使用API会导致软件质量下降、安全性降低。更有效、侵入性更低的方法已变得普遍,通常受到用户和安全Maven的青睐。
因此,我们建议从C标准的下一个修订版中删除附录K,或者先弃用再删除。

相关问题