3
// in someFile.h or someFile.cpp
TEST()
{
    "example test", []
    {
         EXPECT(0 == 1);
    }
}
TEST_END()

// in main.cpp
int main() { ssvu::Test::runAllTests(); }

#define TEST() static RunOnCtor UNIQUENAME(__LINE__) { []{ getStaticTests().push_back({
#define TEST_END() });}};
struct RunOnCtor { RunOnCtor(std::function<void()> f) { f(); } };

我创建了一些单元测试宏,它们在头文件(对我的仅头文件库有用)和源文件中都有效。

TEST()创建一个 的静态实例RunOnCtor,该实例在构造时执行一个 lambda,该 lambda 将测试 lambda插入到一个std::vector测试中。runAllTests()运行该向量中的每个测试。

我创建了一个DISABLE_TEST简单地放在lambdareturn;开头的定义RunOnCtor,因此不会向内部向量添加任何测试。但是,我想在禁用测试时防止不必要的静态对象构造。

有没有办法完全忽略和之间的TEST()一切TEST_END()?就像评论它一样。或者清空RunOnCtor(空结构)会使编译器避免静态结构?

4

2 回答 2

4

我认为这应该有效:

#define TEST() struct UNIQUENAME(__LINE__) { void f() {

#define TEST_END() } };
于 2013-09-11T13:47:39.257 回答
2

以下内容基于 @Angew 的回答,但使用标准预处理器定义。然后该类在类声明中定义一个函数,在 C++ 中该函数强制它是内联的。因为永远不会实例化类并且永远不会调用函数,所以永远不会生成任何代码。

#define CAT(a, ...) PCAT(a, __VA_ARGS__)
#define PCAT(a, ...) a ## __VA_ARGS__
#define TEST() class CAT(Obfuscate_, __LINE__) { void f() {
#define TEST_END() } };

int c;
TEST()
    int a = 7;
    int b = a * 17;
    c = b + 4;
    return;
TEST_END()

这是 Godbolt 的方便的编译器资源管理器,用于证明 GCC、CLANG 和 ICC 不会为上述内容生成代码:https ://godbolt.org/g/BXKDNF

于 2016-12-15T15:30:23.460 回答