выбросить const / volatile из указателя или ссылки

Это часть моего кода …
Как я знаю, кастинг правильный, как я сделал ниже, но я получаю предупреждение о моей логике. Можете ли вы объяснить, почему это так?
Часть моего кода:

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

0

Решение

Как я знаю, кастинг правильный, как я сделал ниже …

Почему вы думаете, что ваш кастинг «правильный»? У тебя есть 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

Другие решения

Это так, потому что вы играете с огнем. Вы не используете систему типов, вы ее обходите. Есть намного лучшие способы сделать это в C ++, такие как:

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

или же

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

Проблема в том, что вы отбрасываете постоянство. Вам не нужно делать это в любом случае, если вы просто собираетесь использовать 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).

1

Как вопрос помечен 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 если подходит.

0
По вопросам рекламы [email protected]