Ale*_*eur 1 c parameters gcc pointers function
在对不希望在目标HW上运行的软件进行C代码审查期间,在功能使用中发现了以下不一致:
SW组件1实现了以下功能:
void foo(uint8 par_var[2])
Run Code Online (Sandbox Code Playgroud)
该函数foo()还会写入par_var数组的两个元素.
SW组件2获得foo()的外部声明,如下所示
extern void foo(uint8 *par_var)
Run Code Online (Sandbox Code Playgroud)
并使用如下:
uint8 par_var;
foo(&par_var); //-> sending a pointer to a scalar
// instead to an array of 2 elements.
Run Code Online (Sandbox Code Playgroud)
显然,它可能导致并导致程序失败.
问题是,例如,如果编译器/链接器可以通过发出警告来拦截不一致性.
我已经扫描并尝试了一些gcc(CygWin)编译器选项以及标准选项(-Wall,-pedantic)https://gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Warning-Options. HTML
但找不到可以发出相应警告的人.
有一个C功能可以帮助编译器诊断它,但我不知道编译器利用它并发出警告.如果foo声明为void foo(uint8 par_var[static 2]);,那么调用者需要将指针传递给至少两个元素,根据C 2018 6.7.6.3 7:
如果关键字
static也出现在数组类型派生的[和]中,那么对于每次对函数的调用,相应的实际参数的值应该提供对数组的第一个元素的访问,其中至少有与该大小指定的元素一样多的元素.表达.
因此,编译器uint8 par_var; foo(&par_var);可以识别无法传递两个元素并提供警告.(虽然我不知道检查声明大小的编译器,但是一些编译器会在为这样的参数传递空指针时发出警告.)
众所周知,在声明中void foo(uint8 par_var[2]),par_var会自动调整为uint8 *par_var.作为替代方案,uint8您可以通过uint8声明foo为指针将指针传递给数组,而不是传递指针void foo(uint8 (*par_var)[2]);.
然后你必须传递一个数组,例如:
uint8 A[2];
foo(&A);
Run Code Online (Sandbox Code Playgroud)
如果使用指针调用它uint8,编译器应发出警告.不幸的是,这也限制了常规; 你必须传递一个指向两个数组的指针,uint8并且不能将指针传递给更大的数组或指向更大数组的指针uint8.因此它的使用有限.尽管如此,它可以在某些情况下发挥作用.