使用特定库的功能

时间:2013-04-25 07:04:58

标签: c++ c

我遇到了问题:我想使用库abs的函数complex

但是,我发出错误警告我abs使用的函数是#define abs(x) (x > 0) ? x : -(x)

因此,我认为问题来自我的进口。由于我还包括stdio和stdlib库,编译器可能会使用其中一个库中定义的函数abs

所以我的问题是:如何在不删除任何导入的情况下使用库abs的函数complex

非常感谢您的回复。

4 个答案:

答案 0 :(得分:15)

包裹它周围的parens。

(abs)(whatever);

这将强制编译器使用函数版本,因为宏不再匹配。

类似函数的宏通过匹配标识符后跟左侧的(来工作。由于我们已将函数名称本身包装在parens中,因此我们将使用一个标识符,后跟一个右侧的paren ),它无法与宏匹配。 parens语义透明,但它们禁止宏语法。

IIRC,是splint C检查员向我讲授这个。在编写postscript解释器时,我创建了很好的短宏来访问堆栈。

#define push(o) (*tos++ = (o))
#define pop() (*--tos)

在涉及tos的表达的一部分之前,哪些部分很有用。为了避免未定义的行为,我不得不创建函数版本并将它们用于那些棘手的问题。对于新设计,我完全跳过了宏。


编辑:我有一种唠叨的感觉,实际上它是Coelocanthe的书(Peter Van Der Linden的 Deep C Secrets ),我在那里学到了这一点,上面的情况是我第一次 它。 IIRC他的例子涉及putchargetchar,它们通常作为符合C实现的函数和宏实现。

答案 1 :(得分:6)

使用#undef

#include "header1.h"
#include "header2.h"
#undef abs // remove abs macro

x = std::abs(y);

答案 2 :(得分:4)

虽然上面的一些建议非常好,但我会采取完全不同的角度。几乎可以肯定的是windows.h导致abs()的“坏”宏定义。您应该不能在执行复杂数学的文件中包含“windows.h”[在大多数类型的程序中,至少](我不知道Windows中的单个函数需要complex<T>作为一个参数,所以我很确定你在同一个源文件中不需要“complex.h”和“windows.h”。这个方法叫做“隔离系统依赖”,这样做非常好事情。

查看您的代码,找到您实际使用Windows函数的位置,然后仅在实际需要它的文件中包含“windows.h”。您可能会发现,如果您使用的是Visual Studio,那么“windows.h”将作为“stdafx.h”的一部分包含在内,这意味着所有类型的有趣宏等都包含在所有地方,因为“stdafx” .h“包含在所有源文件中。

答案 3 :(得分:1)

#undef和括号解决方案都可行,但我建议稍微强一些,因为这两种解决方案都要求你每次打电话abs时都要这样做,下次你可能会忘记并导致错误。

你能做什么:

  1. 将您的函数名称更改为不太常用的名称:absolutemyAbs等...
  2. 在名称空间下放置function \ class(对于C ++而不是C),然后调用是显式的myNameSpace::abs(x)
  3. 如果它不起作用,这里的评论建议我仍然会在我的功能中扭曲这个电话:

    输入myAbs(类型参数) {     return(abs)(param); }