Я создаю библиотеку только для заголовков, и я хотел бы, чтобы предупреждения отображались во время компиляции. Однако кажется, что отображаются только предупреждения для «основного» проекта, включая библиотеку, но не для самой библиотеки.
Есть ли способ заставить компилятор проверить наличие предупреждений во включенной библиотеке?
// 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/
каталог), или локально с "..."
,
Я предполагаю, что у вас есть библиотека шаблонов, и вы жалуетесь на отсутствие предупреждений от ее компиляции. Не ищи плохого #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
), что делает его кандидатом для оптимизации (но это зависит), а также означает, что значения, передаваемые функциям, не обязательно должны быть действительными значениями, так как код никогда не будет выполняться (это сэкономит вам выделение массивов или подготовку любых данных функции могут понадобиться).
С другой стороны, поскольку вам придется писать много кода, чтобы действительно проверить все функции, вы также можете передавать действительные данные и проверять правильность результатов и делать их полезными, вместо того, чтобы, вероятно, запутать кого-то, кто читает код после вас (как, вероятно, в приведенном выше случае).