禁用__LINE__宏?

时间:2012-07-31 15:37:12

标签: c++ macros

我想做一些异常处理。我计划使用__LINE____FILE__宏。

我有一些标题Vectors.hpp,其中我实现了一个矢量结构的类。在这个类中,我实现了operator [],并且我希望每次将此运算符与out of bounds索引一起使用时抛出异常。我在一些源test.cpp中测试了这个类。我希望能够在test.cpp中看到确切的行。

但是我知道每次包含一些标题时都会禁用__LINE__宏,所以我得到的是Vectors.hpp中的行,我处理异常而不是test.cpp中的行。有没有一个好方法来解决这个问题?或者,如何实现自己的__LINE__宏?

3 个答案:

答案 0 :(得分:5)

永远不会禁用__LINE__宏。在您编写它的地方扩展它。编写代码有两种方法(更准确地说,有两种方法可以生成令牌):

  • 手动编写
  • 使用预处理器编写代码

如果你有这样的文件foo.cpp就像这样(只是示例性的,实际上是非常糟糕的代码)

class Foo {
public:
    Frob operator[] (size_t) { throw __LINE__ }
};

然后__LINE__始终为3,__FILE__始终为foo.cpp

这是因为宏在使用它们的地方被扩展。解决方案是找到一种方法将它们扩展到你想要的它,并且唯一的方法是定义另一个宏:

#define safe_subscript(foo, index) \
      try {foo[index];} \
      catch(...) { std::cout << __LINE__ << '\n'; }

....
safe_subscript(foo, 256);

但正如您所看到的,这会导致相当丑陋的代码和变通方法。

真正的解决方案:只需在越界(throw std::out_of_range)之外抛出异常,或者像the standard library那样抛出异常:

T& operator[] (size_type i) { return store_[i]; }
T& at (size_type i) { if (i>size_) throw std::out_of_range("crap");
                      return store_[i]; }

T operator[] (size_type i) const { return store_[i]; }
T at (size_type i) const { if (i>size_) throw std::out_of_range("crap");
                           return store_[i]; }

如果您的用户收到异常,他应该调试他/她/ 发生编程错误的位置。

答案 1 :(得分:1)

您可以将当前行作为异常的一部分传递。将您的例外定义为

struct MyException : public std::exception {
    MyException(const char* line) : errorLine(line);
    const char* errorLine;
};

使用如下:

if (isError())
     throw MyException(__LINE__);

答案 2 :(得分:0)

很简单,你必须在捕获异常时添加该信息,通常我们创建一个扩展std :: exception的类,其中包含一些用于挂载清除错误消息的附加属性,其中包含__LINE____FILE__甚至是__FUNCTION__

这个也回答了这个问题: Getting information about where c++ exceptions are thrown inside of catch block?