传递给函数时,如何强制警告使用错误大小的数组? [英] How do I force a warning from using an array of wrong size when passed to function?

查看:41
本文介绍了传递给函数时,如何强制警告使用错误大小的数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个将字符串作为参数的函数:

Let's say you have a function taking a string as an argument:

void foo(char *arg);

如果我们确定数组(不要与字符串长度混淆,谢谢chux)总是有一定的大小,比如说8,那么我们可以改为:

If we know for certain that the array (not to be confused with string length, thanks chux) will always have a certain size, let's say 8, then we can instead do:

void bar(char (*arg)[8]);

然后像这样调用它:

char str[8] = "Hello";
bar(&str);

我们需要添加 & 以使其正常工作,但是如果您传递大小或类型错误的数组,上面的代码将发出警告,这正是我想要实现的.但是我们显然需要稍微修改一下身体.所以我的问题很简单:这种包装技术是否可行:

We need to add the & for this to work properly, but the above code will emit a warning if you pass an array of wrong size or type, which is exactly what I want to achieve. But we will obviously need to modify the body a bit. So my question is simply if this wrapper technique would work:

void bar(char (*arg)[8]) {
    char *tmp = (char*) arg;
    foo(tmp);
}

我在这里试图实现的是,如果使用大小错误的数组调用,则应发出警告.上述解决方案安全吗?将指向char数组的指针转换为指向char的指针是否安全?我试过了,它可以工作,并且没有使用 -Wall -Wextra -pedantic 发出警告.一旦我改变了 str 的大小,我就会得到:

What I'm trying to achieve here is that warnings should be emitted if called with an array of wrong size. Is the above solution safe? Is it safe to cast pointer to array of char to pointer to char? I tried it, and it works, and emits no warnings with -Wall -Wextra -pedantic. And as soon as I change the size of str I get:

<source>: In function 'main':
<source>:18:9: warning: passing argument 1 of 'bar' from incompatible pointer type [-Wincompatible-pointer-types]
   18 |     bar(&str);
      |         ^~~~
      |         |
      |         char (*)[9]
<source>:9:17: note: expected 'char (*)[8]' but argument is of type 'char (*)[9]'
    9 | void bar(char (*arg)[8]) {
      |          ~~~~~~~^~~~~~~

这正是我想要的.但它是安全的,还是UB?我想这样做,不仅通过包装器,而且还通过重写原始函数,如

which is exactly what I want. But is it safe, or is it UB? I would like to do this, not only via a wrapper, but also by rewriting the original function, like

void foo(char (*argaux)[8]) {
    char *arg = *argaux;
    // Copy body of original foo

我知道我可以使用结构实现基本相同的目的,但我想避免这种情况.

I know that I can achieve basically the same thing using structs, but I wanted to avoid that.

可运行代码:https://godbolt.org/z/GnaP5ceMr

推荐答案

char *tmp = (char*) arg; 是错误的,这些不是兼容的指针类型.不过,您可以轻松解决此问题:

char *tmp = (char*) arg; is wrong, these are not compatible pointer types. You can fix this easily though:

char *tmp = *arg;

*arg 给出一个 char[8],然后它会衰减为指向其第一个元素的指针.这是安全且定义明确的.是的,指针具有更强的打字"功能.在 C 中而不是按值传递,因此编译器会识别是否传递了错误大小的数组.

*arg gives a char[8] which then decays into a pointer to its first element. This is safe and well-defined. And yes, pointers have much stronger "typing" in C than pass-by-value, so the compiler will recognize if an array of wrong size is passed.

但是请注意,这会导致其他问题:您不能再拥有 const 正确性.
请参阅数组指针的常量正确性?

Please note however that this leads to other problems: you can no longer have const correctness.
See Const correctness for array pointers?

这篇关于传递给函数时,如何强制警告使用错误大小的数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆