【问题标题】:Is it possible to prevent a macro from hiding a function?是否可以防止宏隐藏函数?
【发布时间】:2020-03-02 15:50:00
【问题描述】:

出于遗留原因,我有一个宏;称之为#define foo。现在,foo 是一个非函数类型的宏。我需要 foo 在函数调用之前扩展为任何内容,或者编译器可以忽略的内容(例如属性)。

但是,我发现我现在还需要创建一个名为 foo 的函数。

预处理器将函数式宏与非函数式宏区别对待,这意味着可能有一种方法可以使其将foo(...)foo ... 进行不同的转换。但是,我不能将 foo 定义为函数宏。

有什么办法可以解决这个问题吗?

附言“一开始就不要那样做”是没有帮助的。 foo 宏已经存在;更改它是可行的,也不是新引入的功能(这是我无法控制的)。请将讨论限制在按要求回答问题


例子:

#define /* ... magic here ... */

  // void foo(int x, int y); <-- might be in a module

  void bar()
  {
    // First 'foo' has no effect
    // Second 'foo' calls the function 'foo'
    foo foo(42, 7);
  }

【问题讨论】:

  • 我只是建议使用查找和替换
  • @Asadefa,不可信。这个问题存在于一个广泛使用的库中;从字面上看,需要更改数千个项目。而且冲突的功能其实也不是我能控制的。
  • 所以您正在管理一个广泛使用的库?
  • 你能给出一个你想要做什么的真实代码示例吗?
  • 你能和#pragma push_macro(foo)#undef foo...#pragma pop_macro(foo)一起工作吗?

标签: c++ c-preprocessor


【解决方案1】:

不,不可能有一个名称​​上下文是一个宏。要么是#define,要么不是。

这是应避免使用宏或使用SHOUTY 名称的主要原因

【讨论】:

  • 从技术上讲,这是错误的;类似函数的宏只有在以类似函数的方式使用时才是宏。无论如何,我更多地考虑滥用替换限制,但诀窍是让 foofoo(...) 以某种方式导致 不同 替换链。
  • 有(foo)。
  • @GoswinvonBrederlow 防止类似函数的宏扩展,但不会停止常规宏。
  • 那是关于“在上下文中是一个宏”。 foo(...) 和 (foo)(...) 的行为不同,只有第一个扩展了类似函数的宏 #define foo(x) ...。不确定您是否可以用它做任何事情来获得不同的替换链。
  • 可以拥有#define foo(...) (__VA_ARGS__),它允许你声明void foo foo(int) {}。但是你在呼叫站点有foo foo(1);
【解决方案2】:

在宏之前声明foo函数并定义goo函数

void foo();
inline void goo(){
    foo();
}
#define foo

可以调用goo函数,宏展开后会内联。

foo goo();

在文件底部定义foo,或者在顶部声明为extern并在另一个文件中。

#undef foo
void foo(){
}

【讨论】:

    【解决方案3】:

    这样做的唯一方法是定义 foo 和 foo(...)。但是你会得到:

    foo.cc:2:0: warning: "foo" redefined
    

    你不能同时定义两者。

    您必须将函数命名为其他名称。

    【讨论】:

      【解决方案4】:

      您只能阻止 类函数 宏扩展。例如:

      #include <iostream>
      
      int foo() { return 2; }
      
      #define foo() 1
      
      int main() {
          std::cout << foo() << '\n';   // Outputs 1.
          std::cout << (foo)() << '\n'; // Outputs 2.
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-16
        • 1970-01-01
        • 2011-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多