【发布时间】:2011-03-28 12:00:55
【问题描述】:
我将NULL_PTR 定义为0U
然后以 NULL_PTR 作为参数调用一个函数。
read_some_data(2U, (uint8_t *const) NULL_PTR, (uint8_t *const) NULL_PTR);
被调用函数原型:
int16_t read_some_data(const uint8_t id, uint8_t *const data_1, uint8_t *const data_2);
在编译时,Misra 引发了违反规则 11.3 的错误。(不应在指针类型和整数类型之间执行强制转换。)
但如果我只是通过NULL_PTR如下,没有违规。
read_some_data(2U, NULL_PTR, NULL_PTR);
哪种方法更好?禁止 Misra 11.3 规则还是直接通过 NULL_PTR 而不进行强制转换?
【问题讨论】:
-
NULL_PTR 应定义为
(void *)0。请注意,这与 C++ 不同,您可以将其定义为0。 -
@Paul R. 为什么?
0u在 C 和 C++ 中都是空指针常量。(void*)0是 C 中的空指针常量,但在 C++ 中不是。NULL_PTR是否打算具有指针类型或作为空指针常量是模棱两可的,所以我没有任何反对它是(void*)0,但大概以这种方式定义它会触发米斯拉规则,所以无论如何都不是一个选择。在 C++ 中,它几乎 必须 是整数类型才有用,因为没有从void*到其他指针类型的隐式转换,所以(void*)0不能在没有强制转换的情况下分配。跨度> -
AFAIK,它具有整数类型而不是指针类型的主要问题是,当您在不强制转换的情况下愚蠢地在可变参数中使用它时会发生什么,因为人们错误地认为他们知道 NULL 具有什么类型,并且更有可能错误地认为它是一个指针,而不是错误地认为它特别是
int而不是另一个整数类型。如果 Misra 禁止强制转换,那么你就完蛋了,你必须创建一个临时指针变量来包含该值。这同样适用于未原型化的函数调用,但 Misra 肯定也会禁止这些调用吗? -
如果 Misra 11.3 不允许
(void *)0,它是什么样的愚蠢规则?该表达式保证产生一个空指针常量。 -
MISRA 不禁止强制转换 - 但 0u 不是指针,它是一个整数值。 @PaulR 是正确的!