Menu

CppCheck 2.14 false positive

2024-05-10
2024-05-13
  • Rob Deckers

    Rob Deckers - 2024-05-10

    I seem to be getting a false-positive in this code:

    template <typename ValueType, std::size_t Size>
    class CircularBuffer
    {
    public:
        bool canWrite() const
        {
            return getNrWritable() > 0;
        }
    
        std::size_t getNrWritable() const
        {
            return Size - getNrReadable();
        }
    
        std::size_t getNrReadable() const
        {
            return (Size + writeIndex_ - readIndex_) % Size;
        }
    

    CppCheck states:

    CircularBuffer.hpp:30:32: style: Return value 'getNrWritable()>0' is always true [knownConditionTrueFalse]
            return getNrWritable() > 0;
                                   ^
    CircularBuffer.hpp:30:29: note: Calling function 'getNrWritable' returns !<=33
            return getNrWritable() > 0;
                                ^
    CircularBuffer.hpp:30:32: note: Return value 'getNrWritable()>0' is always true
            return getNrWritable() > 0;
                                   ^
    

    But a small adjustment of canWrite resolves the false-positive

        bool canWrite() const
        {
            return (Size - getNrReadable()) > 0;
        }
    

    Even though nothing has really changed

     
  • CHR

    CHR - 2024-05-10

    I think this is a true positive, unless Size == 0, and then you have a problem in getNrReadable().
    The result from getNrReadable() is in [0, Size-1], so getNrWritable() is positive.

     
  • Rob Deckers

    Rob Deckers - 2024-05-13

    Still I think there is a problem here.

    1. If it's a true positive, it should not be resolved by: "return (Size - getNrReadable()) > 0;", cause it's the same.
    2. I might have given a too simplified example, cause getNrReadable also can return Size itself.
    std::size_t getNrReadable() const
        {
            if (writeIndex_ >= Size) {
                return Size;
            }
    
            return (Size + writeIndex_ - readIndex_) % Size;
        }
    

    where if (writeIndex_ >= Size) can become true due to other parts of the code.

    I asked GitHub copilot why Cppcheck provides this error and I received:

    The cppcheck warning "Return value 'getNrWritable()>0' is always true" is indicating that the function canWrite() will always return true.

    The canWrite() function returns the result of getNrWritable() > 0. The getNrWritable() function returns Size - getNrReadable().

    The getNrReadable() function returns either Size or (Size + writeIndex_ - readIndex_) % Size. In both cases, the value returned by getNrReadable() is less than or equal to Size.

    Therefore, Size - getNrReadable() is always greater than or equal to 0. This means that getNrWritable() > 0 will always be true unless getNrReadable() returns Size, which would make getNrWritable() return 0.

    However, getNrReadable() will only return Size if writeIndex_ >= Size. But in the markWritten() function, if writeIndex_ == readIndex_, writeIndex_ is increased by Size, making it greater than Size. This means that writeIndex_ >= Size can be true, and therefore getNrReadable() can return Size, making getNrWritable() return 0, and canWrite() return false.

    So, it seems like there might be a mistake in the cppcheck analysis. It's possible that cppcheck is not correctly understanding the logic of your code.

     

    Last edit: Rob Deckers 2024-05-13
  • CHR

    CHR - 2024-05-13

    Thanks for reporting, ticket is here: https://trac.cppcheck.net/ticket/12727
    Good thing that you marked the AI drivel, so I could skip over that ;)

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.