如何在没有警告的情况下传递用户定义的固定长度数组类型(C和OpenCL)



我有几个理由为固定长度的数组定义一个类型,如下所示:

typedef float fixed_array_t[NX][NY];

然后我想将对fixed_array_t实例的引用传递给其他函数。虽然我看到正确的行为,但我从GCC和CLANG得到编译器警告。

这个编译器警告告诉我什么,我的代码应该如何修改以避免警告?额外的好处是,为什么我要#define数组的大小?编译时常量显然不起作用。error: variably modified ‘fixed_array_t’ at file scope

下面是一个小的演示代码:

#include <stdio.h>
#define NX 2  // also, why does const int NX = 2; not work?
#define NY 3
typedef float fixed_array_t[NX][NY];
void array_printer( const fixed_array_t arr )
{
    int i, j;
    for (i = 0; i < NX; i++ )
        for( j=0; j < NY; j++ )
            printf("Element [%d,%d]=%fn", i,j, arr[i][j] );
}
int main( int argc, char ** argv )
{
    fixed_array_t testArray = { {1,2,3}, {4,5,6} };
    array_printer( testArray );
}

GCC警告:

warning: passing argument 1 of ‘array_printer’ from incompatible pointer type

CLANG警告(实际在OpenCL中编译等效代码):

warning: incompatible pointer types passing 'fixed_array_t' (aka 'real [2][3]'), expected 'real const (*)[3]'

程序运行正常:

Element [0,0]=1.000000
Element [0,1]=2.000000
Element [0,2]=3.000000
Element [1,0]=4.000000
Element [1,1]=5.000000
Element [1,2]=6.000000

我认为这是一个问题的原因是array_printer可以传递它认为是const char(通过指针引用),但调用代码有一个非const引用,因此可以改变指向的值。

尝试改变:

void array_printer( const fixed_array_t arr )

void array_printer( fixed_array_t arr )

这只是c语言中一个不幸的角落。

形式参数const fixed_array_t arr的类型是const float (*arr)[XY]的同义词,实际参数totalArray的计算结果为float (*)[XY]类型。

A pointer to array XY of float 不被认为隐式地转换为 pointer to array XY of const float

如果你只是想解决这个问题,你可以使用struct来封装你的数组:

$ cat struct.c ; make CFLAGS=-Wall -Wextra struct ; ./struct
#include <stdio.h>
#define NX 2
#define NY 3
typedef struct fixed {
    float arr[NX][NY];
} fixed_t;
void array_printer( const fixed_t f)
{
    int i, j;
    for (i = 0; i < NX; i++ )
        for( j=0; j < NY; j++ )
            printf("Element [%d,%d]=%fn", i,j, f.arr[i][j] );
}

int main(int argc, char *argv[]) {
    fixed_t f = {.arr={ {1,2,3}, {4,5,6} }};
    array_printer(f);
    return 0;
}
cc -Wall    struct.c   -o struct
Element [0,0]=1.000000
Element [0,1]=2.000000
Element [0,2]=3.000000
Element [1,0]=4.000000
Element [1,1]=5.000000
Element [1,2]=6.000000

没有警告,没有错误,只是稍微让人讨厌一点(例如,array_printer中的f.arr[][]而不是arr[][])。

如果你修改struct fixed以包含NXNY维度,你甚至可以在你的程序中有多个不同大小的对象。(虽然您会稍微失去编译时间已知边界的好处,但我不确定这到底给您带来了多少好处。)

相关内容

  • 没有找到相关文章

最新更新