【问题标题】:Is it possible to modify the "function call" at the preprocessing time or the compile time是否可以在预处理时或编译时修改“函数调用”
【发布时间】:2014-09-17 09:03:47
【问题描述】:

第一个问题:是否可以调用带有一些参数的函数,并在编译后在预处理时或在编译时修改为其他东西

#define func(a,b) func(a,sizeof(a),b)

有些人可能会认为为什么会出现这种需求。

实际上,我正在使用 Visual Studio 2010 在 Windows 中移植代码,并且有些函数已被弃用,例如 strcpy()、strcat() 等。它说要改用 strcpy_s()。

我知道我可以使用 #pragma disable(warning: ) 或提供如下标志来抑制它:

_CRT_NONSTDC_NO_DEPRRECATE
_CRT_SECURE_NO_DEPRECATE
_CRT_SECURE_NO_WARNINGS

但我不想忽视或压制他们。

我试图只是简单地替换字符串而不是通过使用忽略:

#define strcpy strcpy_s

在这里http://msdn.microsoft.com/en-us/library/td1esda9.aspx 我读到如果我不提供第二个参数,就不会有参数不匹配。

我的意思是如果我这样使用应该没问题:

#define strcpy strcpy_s
strcpy(dest,src);

但事实并非如此。它仍然会产生警告。

strcpy_s的定义是:

errno_t strcpy_s(
   char *strDestination,
   size_t numberOfElements,
   const char *strSource 
);

第二个问题:第一个参数是一个指向动态分配内存的指针,那么我怎样才能得到这个指针所指向的内存大小。虽然我读到这是不可行的,但必须有某种方式(希望如此)。

顺便问一下_countof(var)是什么?

【问题讨论】:

  • 请,请不要这样做。使用其他版本或关闭这些警告。
  • 1.这不是strcpy_s 的唯一定义,因为您方便地省略了从固定数组推断大小的the template versions。 2. 没有可移植的方法来获取动态分配的大小,只给它指向原始内存的指针。我同意博士的观点。不要这样做。如果您想使用运行时库的安全版本,请使用它们。 3._countofdocumented here
  • +1 仅仅因为问题中可能的解决方案很糟糕并不意味着这个问题很糟糕。至于答案,如果您需要构建跨平台,请避免使用非标准功能。并且不要太用力地对抗语言。
  • 我建议您忽略弃用警告。只有一种 C 语言 (Microsoft) 实现声称这些函数已被弃用。事实上,像strcpy_s 这样的函数很少提供额外的安全性,并且在大多数其他平台上不可用,从而大大降低了程序的可移植性。
  • 1.对不起@WhozCraig我的错误我不认为函数定义会改变它是c还是c++。实际上,我正在专门使用 C 语言,所以模板版本已经出来了。 2.你说没有便携的方式那么还有其他的技术吗。

标签: c visual-studio-2010 macros preprocessor-directive


【解决方案1】:

这些函数已被弃用。 Microsoft 试图通过错误地声称它们已被弃用来诱使您编写特定于 Microsoft 的代码,即使 ISO WG14 委员会(负责它们的人)没有做出这样的声明。

定义三个_CRT 宏应该被认为是使编译器进入“稍微接近标准”模式的正确方法,就像/Za 一样。

【讨论】:

    【解决方案2】:

    作为 MSalters stated,这些函数并没有被弃用,它们是标准 C 的一部分。如果使用得当,它们是安全的,并且抑制这些警告没有任何问题,尤其是在编写可移植代码时。 (它们(可能只是其中的一部分,不知道)在C11标准的Annex K中有标准化,不是强制性的。)

    但我不想忽视或压制他们。

    为什么?不压制警告本身并不是一件好事。

    我试图只是简单地替换字符串而不是通过使用忽略:

    #define strcpy strcpy_s
    

    这仅适用于 C++(并且仅适用于 MS Windows,我不知道 C++ 是否指定了类似于 C11 的附件 K 的内容),即使在那里,也仅适用于数组参数。在 C 中,您可以获得类似的行为:

    #define IS_ARRAY(arr) ((char *)(arr) == (char *)&(arr))
    #define my_strcpy(a, b) ( assert(IS_ARRAY(a)) ,
                              strcpy_s((a), sizeof(a), (b)) )
    

    甚至是静态断言——例如Gcc 允许将其作为常量表达式;该标准允许但不要求它——这将允许您在编译时找到所有出现的指针参数并手动“修复”它们。 (同样,这不是一个修复,要么代码已经使用 strcpy 安全,要么仍然不安全,只是更有可能崩溃。)

    请注意,如果定义了具有标准库函数名称的宏(如果包含相关的标头),则行为未定义。因此,我假设 strcpy 调用已经被 my_strcpy 替换。

    (另请注意,请始终将宏参数括起来,如上所示。)

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      • 2017-06-15
      • 2020-10-17
      • 2012-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多