如何传递用户定义的固定长度数组类型而不发出警告(C 和 OpenCL)

发布于 2024-12-14 19:20:19 字数 1289 浏览 2 评论 0原文

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

typedef float fixed_array_t[NX][NY];

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

这个编译器警告告诉我什么以及我的代码应该如何修改以避免警告?另外,为什么我必须#define数组大小?编译时常量显然不起作用。 错误:在文件范围内可变地修改了'fixed_array_t'

这是一个小演示代码:

#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]=%f\n", 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

I have a few reasons to define a type for a fixed length array such as this:

typedef float fixed_array_t[NX][NY];

I then want to pass references to fixed_array_t instances around to other functions. I'm getting a compiler warning from both GCC and CLANG though I'm seeing correct behavior.

What is this compiler warning telling me and how should my code be modified to avoid the warning? Bonus, why do I have to #define the array size? Compile-time constants apparently don't work. error: variably modified ‘fixed_array_t’ at file scope

Here is a small demonstration code:

#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]=%f\n", 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:

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

CLANG warning (actually compiling equivalent code in OpenCL):

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

Yet program operation is fine:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仅冇旳回忆 2024-12-21 19:20:19

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

void array_printer( const fixed_array_t arr )

尝试改变

void array_printer( fixed_array_t arr )

I think the reason this is a problem is that array_printer can pass what it thinks is const char (by reference via pointer), yet calling code has a non-const reference and hence can change the values pointed to.

Try changing:

void array_printer( const fixed_array_t arr )

to

void array_printer( fixed_array_t arr )
魂ガ小子 2024-12-21 19:20:19

这只是 C 中的一个不幸的极端情况。

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

指向 float 数组 XY 的指针 根本不被视为可隐式转换为 指向 const float 数组 XY 的指针 。也许应该是这样,但事实并非如此。

This is simply an unfortunate corner-case in C.

The type of the formal parameter const fixed_array_t arr is a synonym for const float (*arr)[XY], and the actual parameter totalArray evaluates to type float (*)[XY].

A pointer to array XY of float is simply not considered implicitly convertible to an pointer to array XY of const float. Perhaps it ought to be, but it isn't.

心头的小情儿 2024-12-21 19:20:19

如果你只是想解决问题,你可以使用 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]=%f\n", 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

没有警告,没有错误,只是使用起来稍微有点烦人 (f.arr[][]<例如,/code> 而不是 array_printer 中的 arr[][])。

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

If you just want the problem solved, you can use a struct to encapsulate your array:

$ 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]=%f\n", 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

No warnings, no errors, and only slightly more annoying to use (f.arr[][] rather than arr[][] in the array_printer, for example).

If you amend the struct fixed to include the NX and NY dimensions, you could even have multiple different-sized objects in your program. (Though you'd slightly lose the benefits of compile-time-known bounds, I'm not sure how much that really buys you.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文