这是我代码的一部分...
正如我在下面所做的那样,我知道铸造是正确的,但我的逻辑得到了 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
据我所知,选角是正确的,就像我在下面所做的那样......
为什么你认为你的选角是"合适的"? 您有const
参数,并且您无缘无故地从中删除了const
-ness。 系统上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
。