When making the following code:
#include <general.dep>
typedef struct {
} obj;
int f1(obj **o) {
return 0;
}
int f2(obj *const *o) {
return 0;
}
int f3(const obj **o) {
return 0;
}
int f4(const obj *const *o) {
return 0;
}
int main() {
obj **o;
f1(o);
f2(o);
f3(o);
f4(o);
return 0;
}
I get the following warning messages:
gcc t1.c -I/home/hamidi/code/lib/general/inc -fmax-errors=1 -lgeneral -llzma -pthread -o t1
t1.c: In function ‘main’:
t1.c:26:6: warning: passing argument 1 of ‘f3’ from incompatible pointer type [-Wincompatible-pointer-types]
26 | f3(o);
| ^
| |
| obj ** {aka struct <anonymous> **}
t1.c:14:20: note: expected ‘const obj **’ {aka ‘const struct <anonymous> **’} but argument is of type ‘obj **’ {aka ‘struct <anonymous> **’}
14 | int f3(const obj **o) {
| ~~~~~~~~~~~~^
t1.c:27:6: warning: passing argument 1 of ‘f4’ from incompatible pointer type [-Wincompatible-pointer-types]
27 | f4(o);
| ^
| |
| obj ** {aka struct <anonymous> **}
t1.c:18:26: note: expected ‘const obj * const*’ {aka ‘const struct <anonymous> * const*’} but argument is of type ‘obj **’ {aka ‘struct <anonymous> **’}
18 | int f4(const obj *const *o) {
| ~~~~~~~~~~~~~~~~~~^
How can I resolve these warning issues?
Update
I tagged the functions which issue the warning below:
void f0(obj **ppo) {}
void f1(const obj **ppo) {} //
void f2(obj const **ppo) {} //
void f3(obj *const *ppo) {}
void f4(obj **const ppo) {}
void f5(const obj const **ppo) {} //
void f6(const obj *const *ppo) {} //
void f7(const obj **const ppo) {} //
void f8(obj const *const *ppo) {} //
void f9(obj const **const ppo) {} //
void fa(obj *const *const ppo) {}
void fb(const obj const *const *ppo) {} //
void fc(const obj const **const ppo) {} //
void fd(const obj *const *const ppo) {} //
void fe(obj const *const *const ppo) {} //
void ff(const obj const *const *const ppo) {} //
I'm not sure which ones are equivalents. It seems that f2 and f3 are different, because f2 issues the warning and f3 doesn't. So, may we say that obj const *
differs from obj *const
?
Update 2
A const for an obj maybe put before or after it, but for pointers it should be put after them. So, let's put const for both after them. Now my question is that in the following code:
void f(int const* const* ppi) {
//**ppi = **ppi;
//*ppi = *ppi;
ppi = ppi;
}
void g(int const* pi) {
//*pi = *pi;
pi = pi;
}
int main() {
int i, *pi = &i, **ppi = π
f(ppi);
g(pi);
return 0;
}
I call two functions, f & g. Both functions prototypes indicate that the argument's content is not altered. g doesn't change the content of the pointer and f doesn't change the content of pointer and the content of where the pointer's content points to.
Now my question is that why does the compiler issue this warning only when f is called, not g?! What should be prototype for f if it wants to say that I'm not going to change the content of the pointer and the content of where it points?
warning: passing argument 1 of ‘f’ from incompatible pointer type [-Wincompatible-pointer-types]
16 | f(ppi);
| ^~~
| |
| int **
t2.c:3:26: note: expected ‘const int * const*’ but argument is of type ‘int **’
3 | void f(int const* const* ppi) {
| ~~~~~~~~~~~~~~~~~~^~~