Это часть моего кода …
Как я знаю, кастинг правильный, как я сделал ниже, но я получаю предупреждение о моей логике. Можете ли вы объяснить, почему это так?
Часть моего кода:
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
Как я знаю, кастинг правильный, как я сделал ниже …
Почему вы думаете, что ваш кастинг «правильный»? У тебя есть 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);
}
Это так, потому что вы играете с огнем. Вы не используете систему типов, вы ее обходите. Есть намного лучшие способы сделать это в C ++, такие как:
static int32 d_cmp(const DApplication *m1, const DApplication *m2)
или же
const DApplication *mi1 = static_cast<const DApplication *>(m1);
Проблема в том, что вы отбрасываете постоянство. Вам не нужно делать это в любом случае, если вы просто собираетесь использовать 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
).
Как вопрос помечен C++
здесь несколько больше похоже на решение C ++.
Это решение решает проблему путем устранение литья, а также делает код чище, безопаснее и, возможно, быстрее.
static
,DApplication
).использование 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'
}
Также вы можете перегружать operator==()
за DApplication
если подходит.