我正在创建一个仅限标头的库,我希望在编译期间显示它的警告。但是,它似乎只是警告" 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/
目录中的文件夹)包含在内,或在"..."
本地版本中使用。
答案 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_y
,T::pub_x
仍然会在没有警告的情况下被忽视。这取决于编译器实现,一些编译器在所有信息可用时执行更积极的检查,其他编译器往往是懒惰的。请注意,T::pub_x
或T::pub_y
都不依赖于模板参数。
可靠地做到这一点的唯一方法是专门化模板并调用函数。请注意,执行该操作的代码不需要可访问(例如在WarningMachine
中),使其成为优化的候选者(但这取决于),并且还意味着传递给函数的值可能不需要是有效值,因为代码永远不会运行(这将节省您分配数组或准备函数可能需要的任何数据)。
另一方面,由于您必须编写大量代码来真正检查所有功能,因此您也可以传递有效数据并检查结果的正确性并使其有用,而不是混淆任何人的地狱谁在您之后读取代码(在上述情况下很可能)。