Menu

constVariable False Positive using >> operator

2021-10-12
2021-10-14
  • Steve Albright

    Steve Albright - 2021-10-12

    The example below does not compile but just pretend it does. I have several of these issues so it is going to make upgrading to 2.60 more painful than it should be.

    Also note, I have run into the situation before where << was used instead of append with Qt containers and I've typically just converted to append but I'd rather not have to fix that code but I didn't come up with a good example to submit but I've seen it multiple times.

    #include <QByteArray>
    
    void constVariableFalsePositiveExample(const QByteArray& buffer)
    {
       unsigned char writeDataHereSoItCannotBeConst[2];
    
       for(int i = 0; i < 2; i++)
       {
          buffer >> writeDataHereSoItCannotBeConst[i]; // ignore compile error because operator int is private
       }
    
       //(void)writeDataHereSoItCannotBeConst; - odd that no warning with this line
    }
    
     
  • Daniel Marjamäki

    I would like to have a compilable example. If buffer is const it seems strange that you can perform a stream read from the object. I guess the compiler tries to compile your code as:

    ((int)buffer) >> writeDataHereSoItCannotBeConst[i]
    

    and in this case the Cppcheck warning is correct.

     
  • Steve Albright

    Steve Albright - 2021-10-13

    Can we not focus on buffer here and what type of class it is?

    CPPCheck is saying to make the unsigned char a const but we are trying to populate it and therefore it can't be const.

    Assume we have an override (friend function or whatever) for >> that reads from buffer (pretend buffer isn't const if that helps) and puts into the unsigned char array.

     
    • Daniel Marjamäki

      I think it's important that it is valid code and compiles in this case. If we always assume that ">>" in various expressions is a stream read and bailout then there will be false negatives. We need to be strict.

      Here is a example code I think seems more proper;

      void foo(std::istream& buffer)
      {
         unsigned char writeDataHereSoItCannotBeConst[2];
      
         for(int i = 0; i < 2; i++)
         {
            buffer >> writeDataHereSoItCannotBeConst[i];
         }
      }
      
       

      Last edit: Daniel Marjamäki 2021-10-13
      • Daniel Marjamäki

         
  • Steve Albright

    Steve Albright - 2021-10-13

    I was working on another repo and found this one where we are writing to *os so it can't be const.

    style: constParameter - Parameter 'os' can be declared with const

    void PrintTo(QString const& foo, ::std::ostream os)
    {
    os << '"' << foo.toStdString() << '"';
    }

     
  • CHR

    CHR - 2021-10-13

    I think the problem is that the overloaded operators << are not part of either std.cfg or qt.cfg, so cppcheck assumes they behave like the regular ones for integers.

     
  • Paul Fultz

    Paul Fultz - 2021-10-14

    Cppcheck knows its a stream operator. The isLikelyStreamRead returns true. The problem is that checkConstPointer doesn't use isVariableChanged(which would recognize the variable being modified).

     

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.