Menu

Division by result of sizeof() when using _countof macro

2020-02-21
2020-02-21
  • Sander Bouwhuis

    Sander Bouwhuis - 2020-02-21

    I have this:

    int32 i32NewLen;
    wchar_t pwcText[256];
    // ...
    memmove(pwcText, &pwcText[i32NewLen], (_countof(pwcText) - i32NewLen) * sizeof(*pwcText));
    

    I get this warning:
    [E:/Development/Dms v5.0.1/Classes/Miscellaneous.cpp:86] (warning) Division by result of sizeof(). memmove() expects a size in bytes, did you intend to multiply instead? [sizeofDivisionMemfunc]

    By multiplying the amount of characters (countof(pwcText) - i32NewLen) with the size of a single character sizeof(pwcText) I get a byte count.

    Doesn't CppCheck understand the countof macro? In Win32 API countof is defined like this:

    #ifdef __cplusplus
        extern "C++"
        {
            template <typename _CountofType, size_t _SizeOfArray>
            char (*__countof_helper(_UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
    
            #define __crt_countof(_Array) (sizeof(*__countof_helper(_Array)) + 0)
        }
    #else
        #define __crt_countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
    #endif
    
     

    Last edit: Sander Bouwhuis 2020-02-21
  • versat

    versat - 2020-02-21

    When specifying a windows platform and/or using the windows library Cppcheck is aware of the _countof macro. This is from windows.cfg:

    <define name="_countof(_Array)" value="(sizeof(_Array) / sizeof(_Array[0]))"/>
    

    Without this library configuration the warning message disappears.
    I guess that Cppcheck issues the warning as soon as it sees the division with the result of the sizeof(). I assume that it is not verified that the number of elements is NOT multiplied with the result of the sizeof() again at a later time.
    Maybe, to avoid false positives, Cppcheck could avoid this warning when more than the division with a sizeof() result is seen. At least it could be marked as inconclusive then.

     
  • versat

    versat - 2020-02-21

    Thank you for the report.
    I created a ticket for the issue: https://trac.cppcheck.net/ticket/9648

     
  • Sander Bouwhuis

    Sander Bouwhuis - 2020-02-21

    This is always how I do it. It's basically, tot_bytes = tot_items * item_size

    I use the same thing for all the places I have to supply a buffer in bytes instead of objects.
    How else would you do it? Is there another way it's done in Linux for instance?

     

    Last edit: Sander Bouwhuis 2020-02-21
    • versat

      versat - 2020-02-21

      I do not see any problem with it, you are correct.
      It is a false positive from Cppcheck, the check should get enhanced I think.

       

      Last edit: versat 2020-02-21
  • Daniel Marjamäki

    yeah it seems to be a bad warning. Your code makes perfect sense.

     

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.