是否可以修改"函数调用"在预处理时或编译时

时间:2014-09-17 09:03:48

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

第一个问题:是否可以使用某些参数调用函数,并且在编译之后,在预处理时或编译时将其修改为其他内容,如

#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我读过,如果我不提供第二个arg,那么论证就不会有不匹配。

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

#define strcpy strcpy_s
strcpy(dest,src);

但不是。它仍会产生警告。

strcpy_s的定义是:

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

第二个问题:第一个参数是一个指向动态分配内存的指针,因此如何获得该指针指向的内存大小。虽然我读到它不可行,但必须有某种方式(希望如此)。

那么什么是_countof(var)

2 个答案:

答案 0 :(得分:2)

这些功能 NOT 已弃用。尽管ISO WG14委员会(负责他们的人)没有做出这样的声明,但微软试图诱使你写出微软特定的代码,并声称他们已被弃用。

定义三个_CRT宏应该被视为将编译器置于“更接近标准”模式的正确方法,就像/Za一样。

答案 1 :(得分:0)

作为MSalters stated,这些函数不被弃用,它们是标准C的一部分。如果正确使用它们是安全的,并且抑制这些警告没有任何问题,特别是在编写可移植代码时。 (他们(可能只是其中一些,不知道)在C11标准的附件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替换。

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