Let's say you have a function taking a string as an argument:
void foo(char *arg);
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]);
and then call it like this:
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);
}
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]) {
| ~~~~~~~^~~~~~~
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.
Runnable code: https://godbolt.org/z/GnaP5ceMr