【问题标题】:#define not executing all arguments#define 不执行所有参数
【发布时间】:2015-03-17 19:51:22
【问题描述】:

我在创建#define 时遇到了问题。由于某种原因,它没有检查语句中的所有参数。

THROW_AND_LOG(Foo::Initialize() && Bar::Initialize() && FooBar::Initialize(), "Something() could not Initialize singletons.");

由于某种原因,它只是初始化 Foo 然后退出语句。它不会抛出或记录。

然而

THROW_AND_LOG((Foo::Initialize() && Bar::Initialize() && FooBar::Initialize()), "Something() could not Initialize singletons.");

出于某种原因工作正常。 (将所有检查括在括号中)。

我将把所有内容移到单独的行来解决这个问题,因为它一开始就不是最好的代码。但是我很好奇为什么它不会执行所有语句。

这里是定义:

#define THROW_AND_LOG(x, message) if(!x) { throw std::runtime_error(message);              \
    LOG::v1::MessageSender messageSender("log");                                           \
    LOGGING_ERROR(messageSender,message);}

【问题讨论】:

  • 为什么这是一个宏?
  • 我正在记录错误并抛出错误,并被告知要创建一个宏。创建不必要的宏是问题还是我不​​应该记录和抛出?也许只在最后捕获日志?
  • @marsh:你需要一个宏来获取__FILE____LINE__。但分开关注。为此创建一个宏,获取该信息。其余的使用普通函数。
  • 日志系统实际上已经获取了所有这些信息。虽然在你提到它之前我确实忘记了它。
  • “被告知要制作宏”由谁?

标签: c++


【解决方案1】:

宏展开后,

if(!x)

转换成

if(!Foo::Initialize() && Bar::Initialize() && FooBar::Initialize())

Foo::Initialize() 大概返回true,所以!Foo::Initialize()false 并且其他术语没有被执行(更不用说它们的含义已经变成了相反的)。

【讨论】:

    【解决方案2】:

    它并没有像你想象的那样扩展。你想在你的宏中使用(!(x))

    【讨论】:

      【解决方案3】:

      带有宏定义

      #define THROW_AND_LOG(x, message) if(!x) { throw std::runtime_error(message);              \
          LOG::v1::MessageSender messageSender("log");                                           \
          LOGGING_ERROR(messageSender,message);}
      

      调用

      THROW_AND_LOG(Foo::Initialize() && Bar::Initialize() && FooBar::Initialize(), "Something() could not Initialize singletons.");
      

      产生条件

      if(!Foo::Initialize() && Bar::Initialize() && FooBar::Initialize())
      

      相当于

      if((!Foo::Initialize()) && Bar::Initialize() && FooBar::Initialize())
      

      一个好的解决方法是用函数替换宏:

      void throw_and_log_if(
           const bool          condition,
           const Location&     location,
           const string&       message )
      {
          LOG::v1::MessageSender messageSender( "log" );
          LOGGING_ERROR( messageSender, message ); }
          throw std::runtime_error( message );
      }
      

      其中Location 是代表文件和行号的某个类,您可以通过__FILE____LINE__ 宏获取。

      我冒昧地修复了导致无法执行日志记录的错误。


      短期内更简单的解决方法是在宏的条件中在 x 周围使用括号。

      如果您选择了,请记住修复宏中的错误。

      【讨论】:

      • 哦,他们(OP)很难弄清楚 Location 实际上是什么:-P。来吧查克!
      猜你喜欢
      • 2011-03-19
      • 2013-11-17
      • 1970-01-01
      • 1970-01-01
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-22
      相关资源
      最近更新 更多