Menu

Template static_assert error

Nikolai
2016-12-22
2017-01-05
  • Nikolai

    Nikolai - 2016-12-22

    Hi everyone

    I have the following (nonsensical) minimal example code which gives me two cppcheck errors:

    template<typename T, UINT8 ui8Size>
    inline T Filter<T, ui8Size>::filterValue( const T tValue )
    {
    #if __cplusplus > 201103L
        static_assert( 0 < ui8Size, "Filter size must be larger than zero." );  // style duplicateExpression
    #endif
    
        ui8WindowIndex = ( ui8WindowIndex + 1 ) % ui8Size;  // zerodiv error
    
        return aTmpWindow[ ui8Size / 2 ]
    

    Error for static_assert
    2 1.76.1 duplicateExpression style Same expression on both sides of '<'. Finding the same expression on both sides of an operator is suspicious and might indicate a cut and paste or logic error. Please examine this code carefully to determine if it is correct.

    Error for zerodiv
    2 1.76.1 zerodiv error Division by zero. Division by zero.

    Does anyone know if this is a false positive or if not how I can change my code to not get errors.

     

    Last edit: Nikolai 2016-12-22
  • Daniel Marjamäki

    It seems to me that you instantiate the template method with ui8Size=0 somewhere. Then ui8Size is replaced with 0.. so "0 < ui8Size" becomes "0 < 0" and "% ui8Size" becomes "% 0".

    So the warnings are technically correct.

    I don't want that we report duplicateExpression for this code. This is a false positive. I believe there are tickets about this already.

    About the zero division. If you instantiate the method with 0 then you get "% 0" that means division by zero. I don't see why that would be a false positive. So I believe it's only a false positive if you don't instantiate with 0.

     
  • Nikolai

    Nikolai - 2017-01-05

    Dear Daniel,
    thank you for the quick response. I was on holidays and didn't have access to the codebase.

    The point with static_assert is, it should never reach the line,
    ui8WindowIndex = ( ui8WindowIndex + 1 ) % ui8Size; // zerodiv error
    if the class is instantiated with zero, but stop during compliation.

    I found the main issue was due to template specialization. I included a full code example below.
    Cppcheck doesn't take into account that
    template<typename T,="" UINT8="" ui8Size="">
    inline T Filter<T, ui8Size="">::filterValue( const T tValue )
    is never called with 0 because of a specialization above.

    #ifndef CPPCHECKEXAMPLE_HPP_
    #define CPPCHECKEXAMPLE_HPP_
    
    template<typename T, UINT8 ui8Size>
    class Filter
    {
    public:
    
        Filter( void );  /// \brief constructor
        virtual ~Filter( void ) {};  /// \brief destructor
        T filterValue( const T Value );
    protected:
    private:
        UINT8 ui8WindowIndex;
    
        std::array<T, ui8Size> aWindow;
        std::array<T, ui8Size> aTmpWindow;
    };
    
    template<typename T>
    class Filter<T, 0>
    {
    public:
        Filter( void ) {}  /// \brief constructor
        virtual ~Filter( void ) {}  /// \brief destructor
        T filterValue( const T Value ) { return Value; }  /// \brief return original value
    };
    
    template<typename T, UINT8 ui8Size>
    inline Filter<T, ui8Size>::Filter( void ) :
            ui8WindowIndex( 0 )
    {
        aWindow.fill( 0 );
        aTmpWindow.fill( 0 );
    }
    
    template<typename T, UINT8 ui8Size>
    inline T Filter<T, ui8Size>::filterValue( const T tValue )
    {
        aWindow[ ui8WindowIndex ] = tValue;
        ui8WindowIndex = ( ui8WindowIndex + 1 ) % ui8Size;
        return aTmpWindow[ ui8Size / 2 ];
    }
    
    #endif
    
    #include "gtest/gtest.h"
    #include "../CppcheckExample.hpp"
    
    TEST(Filter, PositiveWindow0)
    {
        Filter<UINT16, 0> mf;
    
        EXPECT_EQ( mf.filterValue(1), 1 );
        EXPECT_EQ( mf.filterValue(2), 2 );
    }
    
    TEST(Filter, PositiveWindow3)
    {
        Filter<UINT16, 3> mf;
    
        EXPECT_EQ( mf.filterValue(1), 0 );
        EXPECT_EQ( mf.filterValue(2), 0 );
    }
    
     

    Last edit: Nikolai 2017-01-05

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.