无法获得警告以适用于仅限标头的库

时间:2014-05-08 07:52:30

标签: c++ compilation warnings header-files header-only

我正在创建一个仅限标头的库,我希望在编译期间显示它的警告。但是,它似乎只是警告" main"显示包含库的项目,但不显示库本身。

有没有办法可以强制编译器检查包含的库中的警告?

// main.cpp
#include "MyHeaderOnlyLib.hpp"
int main() { ... }

// Compile
g++ ./main.cpp -Wall -Wextra -pedantic ...

// Warnings get displayed for main.cpp, but not for MyHeaderOnlyLib.hpp

我使用MyHeaderOnlyLib.hpp通过CMake脚本找到find_package。我已经检查了CMake执行的命令,它使用的是-I,而不是-isystem

我已尝试将图书馆与<...>(当/usr/include/目录中的文件夹)包含在内,或在"..."本地版本中使用。

1 个答案:

答案 0 :(得分:2)

我想你有一个模板库,你抱怨它的编译没有警告。不要寻找错误的#include路径,这最终会导致错误。遗憾的是,如果没有专业化(除非模板由.cpp使用),编译器无法可靠地解释模板,更不用说产生明智的警告了。考虑一下:

#include <vector>

template <class C>
struct T {
    bool pub_x(const std::vector<int> &v, int i)
    {
        return v.size() < i;
    }

    bool pub_y(const std::vector<int> &v, int i)
    {
        return v.size() < i;
    }
};

typedef T<int> Tint; // will not help

bool pub_z(const std::vector<int> &v, unsigned int i) // if signed, produces warning
{
    return v.size() < i;
}

class WarningMachine {
    WarningMachine() // note that this is private
    {
        //T<int>().pub_y(std::vector<int>(), 10); // to produce warning for the template
    }
};

int main()
{
    //Tint().pub_y(std::vector<int>(), 10); // to produce warning for the template
    return 0;
}

您可以在codepad中试用。请注意,pub_z将在编译时立即生成签名/无符号比较警告,尽管从未被调用过。不过,这是一个完全不同的模板故事。即使调用了T::pub_yT::pub_x仍然会在没有警告的情况下被忽视。这取决于编译器实现,一些编译器在所有信息可用时执行更积极的检查,其他编译器往往是懒惰的。请注意,T::pub_xT::pub_y都不依赖于模板参数。

可靠地做到这一点的唯一方法是专门化模板并调用函数。请注意,执行该操作的代码不需要可访问(例如在WarningMachine中),使其成为优化的候选者(但这取决于),并且还意味着传递给函数的值可能不需要是有效值,因为代码永远不会运行(这将节省您分配数组或准备函数可能需要的任何数据)。

另一方面,由于您必须编写大量代码来真正检查所有功能,因此您也可以传递有效数据并检查结果的正确性并使其有用,而不是混淆任何人的地狱谁在您之后读取代码(在上述情况下很可能)。