سؤال

I'm creating an header-only library, and I would like to get warnings for it displayed during compilation. However, it seems that only warnings for the "main" project including the library get displayed, but not for the library itself.

Is there a way I can force the compiler to check for warnings in the included library?

// 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

I'm finding MyHeaderOnlyLib.hpp via a CMake script, using find_package. I've checked the command executed by CMake, and it's using -I, not -isystem.

I've tried both including the library with <...> (when it's in the /usr/include/ directory), or locally with "...".

هل كانت مفيدة؟

المحلول

I suppose that you have a template library and you are complaining about the lack of warnings from its compilation. Don't look for bad #include path, that would end up as an error. Unfortunately, without specialization (unless the templates are used by the .cpp), the compiler has no way to interpret the templates reliably, let alone produce sensible warnings. Consider this:

#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;
}

You can try it out in codepad. Note that the pub_z will immediately produce signed / unsigned comparison warning when compiled, despite never being called. It is a whole different story for the templates, though. Even if T::pub_y is called, T::pub_x still passes unnoticed without a warning. This depends on a compiler implementation, some compilers perform more aggressive checking once all the information is available, other tend to be lazy. Note that neither T::pub_x or T::pub_y depend on the template argument.

The only way to do it reliably is to specialize the templates and call the functions. Note that the code which does that does not need to be accessible for that (such as in WarningMachine), making it a candidate to be optimized away (but that depends), and also meaning that the values passed to the functions may not need to be valid values as the code will never run (that will save you allocating arrays or preparing whatever data the functions may need).

On the other hand, since you will have to write a lot of code to really check all the functions, you may as well pass valid data and check for result correctness and make it useful, instead of likely confusing the hell of anyone who reads the code after you (as is likely in the above case).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top