[英]Why does SonarQube raise a MISRA-C critical remark <<Function names should be used either as a call [...]>> on the "startup" code for ARM Cortex-M3?
我遇到了以下 SonarQube 评论 (MISRA-C:2012),在用 C 语言实现启动代码时,对于 ARM Cortex-M3:
函数名称应用作带有参数列表或“&”运算符的调用
具有以下描述:
使用“秃头”函数名可能是一个错误。 它不是使用 void 参数列表测试函数的返回值,而是隐式地检索该函数在内存中的地址。 如果这确实是我们想要的,那么应该使用 & (address-of) 运算符来明确它。 如果不是,则应在函数名称后添加参数列表(即使是空的)。
我正在使用以下编译器:
armclang V6.12,语言为C99
SonarQube 的版本是:
版本 6.7(内部版本 33306)
SonarQube 注释是在向量表数组内的Reset_Handler的引用上引发的。 (见下面的代码)
/*----------------------------------------------------------------------------
Exception / Interrupt Handler Function Prototype
*----------------------------------------------------------------------------*/
typedef void (*pFunc)(void);
/*----------------------------------------------------------------------------
External References
*----------------------------------------------------------------------------*/
extern uint32_t __INITIAL_SP;
extern __NO_RETURN void __PROGRAM_START(void);
/*----------------------------------------------------------------------------
Internal References
*----------------------------------------------------------------------------*/
__NO_RETURN void Default_Handler(void);
__NO_RETURN void Reset_Handler(void);
/*----------------------------------------------------------------------------
Exception / Interrupt Handler
*----------------------------------------------------------------------------*/
/* Exceptions */
void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
/*----------------------------------------------------------------------------
Exception / Interrupt Vector table
*----------------------------------------------------------------------------*/
extern const pFunc __VECTOR_TABLE[16];
const pFunc __VECTOR_TABLE[16] __VECTOR_TABLE_ATTRIBUTE = {
(pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */
Reset_Handler, /* Reset Handler <<<<<------ WHERE THE SONARQUBE REMARK IS */
NMI_Handler, /* -14 NMI Handler */
HardFault_Handler, /* -13 Hard Fault Handler */
MemManage_Handler, /* -12 MPU Fault Handler */
BusFault_Handler, /* -11 Bus Fault Handler */
UsageFault_Handler, /* -10 Usage Fault Handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
SVC_Handler, /* -5 SVCall Handler */
DebugMon_Handler, /* -4 Debug Monitor Handler */
0, /* Reserved */
PendSV_Handler, /* -2 PendSV Handler */
SysTick_Handler, /* -1 SysTick Handler */
};
void Reset_Handler(void)
{
SystemInit(); // CMSIS System Initialization
__PROGRAM_START(); // Enter PreMain (C library entry point)
}
void Default_Handler(void)
{
while (1) {
__asm volatile(""); /* this line is considered to have side-effects */
}
}
我真的不明白为什么它会在那个特定点抱怨,我真的不明白我错过了什么:
- 函数指针定义在开头pFunc
- 返回类型定义为void ,并且函数没有参数
- 向量表数组的类型是“pFunc”
- Default_Handler和Reset_Handler 都匹配函数指针定义的正确原型
任何帮助,将不胜感激。 :)
谢谢你。
@Lundin 我发现了以下不合规代码示例:
int func(void) {
// ...
}
void f2(int a, int b) {
// ...
if (func) { // Noncompliant - tests that the memory address of func() is non-null
//...
}
// ...
}
合规代码:
void f2(int a, int b) {
// ...
if (func()) { // tests that the return value of func() > 0
//...
}
// ...
}
所以你似乎是对的。 该工具认为是一个不同的问题。
SonarQube 警告抱怨您使用了函数的名称而不调用它,怀疑您实际上是打算调用它。
因为函数名会自动转换为指向函数的指针, func
和&func
指的是同一个东西,所以你可以互换使用它们。
由于您不是尝试调用函数而是将它们的地址放在数组中,因此使用 address-of 运算符明确表示您要获取函数的地址而不是调用它以及任何其他函数指针。
extern const pFunc __VECTOR_TABLE[16];
const pFunc __VECTOR_TABLE[16] __VECTOR_TABLE_ATTRIBUTE = {
(pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */
&Reset_Handler, /* Reset Handler */
&NMI_Handler, /* -14 NMI Handler */
&HardFault_Handler, /* -13 Hard Fault Handler */
&MemManage_Handler, /* -12 MPU Fault Handler */
&BusFault_Handler, /* -11 Bus Fault Handler */
&UsageFault_Handler, /* -10 Usage Fault Handler */
NULL, /* Reserved */
NULL, /* Reserved */
NULL, /* Reserved */
NULL, /* Reserved */
&SVC_Handler, /* -5 SVCall Handler */
&DebugMon_Handler, /* -4 Debug Monitor Handler */
NULL, /* Reserved */
&PendSV_Handler, /* -2 PendSV Handler */
&SysTick_Handler, /* -1 SysTick Handler */
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.