从指针或引用中抛弃const / volatile

时间:2014-01-27 10:30:35

标签: c++ lint

这是我的代码的一部分......
据我所知,铸件是正确的,正如我在下面所做的那样,但我得到了我的逻辑的linting警告..你能解释它为什么会这样..
我的部分代码:

typedef struct
{
    char  appid[4];                  /**< application id */
    int32 pid;                      /**< process id of user application */
} DApplication;

static int32 d_cmp(const void *m1, const void *m2)
{
    DApplication *mi1 = (DApplication *) m1;   //Line 1
    DApplication *mi2 = (DApplication *) m2;   //Line 2
    return memcmp(mi1->appid, mi2->appid, 4);  //Line 3
}

And warnings are :                      
Sample.cpp (line 1):Note 960: Violates MISRA 2004 Required Rule 11.5, attempt to cast away const/volatile from a pointer or reference
Sample.cpp (line 2):Note 960: Violates MISRA 2004 Required Rule 11.5, attempt to cast away const/volatile from a pointer or reference
Sample.cpp (line 3):Note 960: Violates MISRA 2004 Required Rule 10.1, Implicit conversion changes signedness

...Courtsey MISRA
As per the MISRA rule :                                              Rule 11.5 (required): A cast shall not be performed that removes any const or volatile
qualification from the type addressed by a pointer.
[Undefined 39, 40]
Any attempt to remove the qualification associated with the addressed type by using casting is a
violation of the principle of type qualification. Notice that the qualification referred to here is not
the same as any qualification that may be applied to the pointer itself.

uint16_t x;
uint16_t * const cpi = &x; /* const pointer */
uint16_t * const * pcpi; /* pointer to const pointer */
const uint16_t * * ppci; /* pointer to pointer to const */
uint16_t * * ppi;
const uint16_t * pci; /* pointer to const */
volatile uint16_t * pvi; /* pointer to volatile */
uint16_t * pi;
...
pi = cpi; /* Compliant - no conversion
no cast required */
pi = (uint16_t *)pci; /* Not compliant */
pi = (uint16_t *)pvi; /* Not compliant */
ppi = (uint16_t * *)pcpi; /* Not compliant */
ppi = (uint16_t * *)ppci; /* Not compliant */                        

SO According to this rule i think it is fine 

4 个答案:

答案 0 :(得分:2)

这是因为你正在玩火。你没有使用类型系统,你正在规避它。在C ++中有更好的方法可以做到这一点,例如:

static int32 d_cmp(const DApplication *m1, const DApplication *m2)

const DApplication *mi1 = static_cast<const DApplication *>(m1);

答案 1 :(得分:2)

  

据我所知,铸件是正确的,正如我在下面所做的那样......

为什么你认为你的演员是“合适的”?您有const个参数,而且您正在删除它们const,这完全没有任何理由。您系统上memcmp()参数的类型是什么?它们应该是const指针 - 来自http://en.cppreference.com/w/cpp/string/byte/memcmp

int memcmp( const void* lhs, const void* rhs, std::size_t count );

所以,你可以像这样修复你的功能:

static int32 d_cmp(const void* m1, const void* m2)
{
    return memcmp(static_cast<const DApplication*>(m1)->appid,
                  static_cast<const DApplication*>(m2)->appid,
                  sizeof DApplication().appid);
}

答案 2 :(得分:1)

问题在于你正在抛弃常量。如果您只是使用memcmp,那么无论如何都不需要这样做,因为它需要(const void*, const void*, size_t)

试试这个:

#include <cstring> // memcmp

typedef struct {
    char appid[4];                /**< application id */
    int pid;                      /**< process id of user application */
} DApplication;

static int d_cmp(const void *m1, const void *m2)
{
    const DApplication *mi1 = static_cast<const DApplication *>(m1);   //Line 1
    const DApplication *mi2 = static_cast<const DApplication *>(m2);   //Line 2
    return memcmp(mi1->appid, mi2->appid, 4);  //Line 3
}

int main(void)
{
    DApplication a1 = {{0,0,0,0}, 1};
    DApplication a2 = {{0,0,0,1}, 1};

    return d_cmp(&a1, &a2);
}

请记住使用c ++编译器进行编译(使用g++而不是gcc)。

答案 3 :(得分:0)

问题被标记C++这里有点像C ++解决方案。

此解决方案通过消除投射来解决问题,并使代码更清晰,更安全,并且可能更快。

  1. 您可以使用匿名命名空间而不是static
  2. 您可以使用功能模板来保持类型安全(如果您需要不同的类型。如果没有,只需硬编码DApplication)。
  3. 无需使用指针。改为使用引用。
  4. 使用std::array代替C风格的数组。它提供operator==()方便(并且更可能,更快)元素比较,因此不需要memcmp

    struct DApplication
    {
        std::array <char, 4> appid;
        int pid;
    };
    
    struct NotDApplication
    {
        int foo;
    };
    
    namespace {
        template <typename T>
        bool CompareAppIds(const T& mi1, const T& mi2)
        {
            return (mi1.appid == mi2.appid);
        }
    }
    
    int main()
    {
        DApplication a, b;
        NotDApplication c, d;
    
        bool isEqual = CompareAppIds(a, b);  // OK
    
        bool isEqual2 = CompareAppIds(c, d); // Compile error: 
                                             // 'appid' : is not a member
                                             // of 'NotDApplication'
    }
    
  5. 此外,如果合适,您可以为operator==()重载DApplication