struct DATA {
char arr[12][12];
};
void test_func(const char (*data)[12]);
const struct DATA cdata = {{{0}}};
struct DATA data;
void testme(void)
{
test_func(cdata.arr);
test_func(data.arr); /* Line 13 */
}
$ gcc -W -Wall -ansi -pedantic -c arr.c
arr.c: In function 'testme':
arr.c:13: warning: passing argument 1 of 'test_func' from incompatible
pointer type
$ g++ -W -Wall -ansi -pedantic -c arr.c
$
It appears to be OK in C++ but not in C. I'm guessing that I'm missing a
const somewhere but I cannot work out where.
I've even tried a typedef const char ARR[12]; and then const ARR* data
parameter but that hasn't worked either. I get exactly the same warning
when I try to pass the non-const version.
(gcc 4.3.2 in case it's a bug in gcc that has been fixed in a later
version)
Tim.
--
God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t,"
and there was light.
> It appears to be OK in C++ but not in C. I'm guessing that I'm
> missing a const somewhere but I cannot work out where.
Have your tried just getting rid of all the consts?
--
Bartc
You're passing it a char * that is not const. The struct is const.
Tom
If the struct is const then any member had better be const otherwise I
can change the struct by passing a pointer to a member.
The line that is giving the problem is not passing a member of a const
struct. The const struct case is working.
I had assumed that this problem was related to:
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17
but it's not quite the same.
However, it appears that gcc also does not like what that says is ok.
void test_func(const char* const * data);
void testme(void)
{
char ** p = 0;
test_func(p);
}
$ gcc -W -Wall -ansi -pedantic -c arr2.c
arr2.c: In function 'testme':
arr2.c:6: warning: passing argument 1 of 'test_func' from incompatible
pointer type
$ g++ -W -Wall -ansi -pedantic -c arr2.c
$
Yes, C and C++ have different rules in this area.
I don't think you can avoid a cast in this case. You can, of course,
ditch all the const qualifiers, but on balance I think they pay their
way -- even though you are sometimes forced to persuade the compiler
to accept your code.
<snip>
--
Ben.
Whoops ya whatever, you're still not passing it a const.
Tom
You're not missing anything, the C rules are different than the C++
rules and don't handle that case. You have to use the cast.
--
Larry Jones
Everybody's a slave to routine. -- Calvin
I don't understand what is logically wrong to increase the strictness
of a datatype when passed to a function like
int a;
funct(a);
int funct(const int);
now here by passing 'a' i am actually imposing some stricter condition
on it ,so why should that be not allowed. I can never do any harm (as
i see).
thanks
Mohan
> On Nov 20, 5:45 pm, Tim Woodall <devn...@woodall.me.uk> wrote:
>> How do I get gcc to like the following code (other than the obvious
>> cast)?
>>
>> struct DATA {
>> char arr[12][12];
>>
>> };
>>
>> void test_func(const char (*data)[12]);
>>
>> const struct DATA cdata = {{{0}}};
>> struct DATA data;
>>
>> void testme(void)
>> {
>> test_func(cdata.arr);
>> test_func(data.arr); /* Line 13 */
>> }
>>
>> $ gcc -W -Wall -ansi -pedantic -c arr.c
>> arr.c: In function 'testme':
>> arr.c:13: warning: passing argument 1 of 'test_func' from incompatible
>> pointer type
<snip>
>> Tim.
[It's best to trim sigs.]
> I don't understand what is logically wrong to increase the strictness
> of a datatype when passed to a function like
> int a;
> funct(a);
>
> int funct(const int);
>
> now here by passing 'a' i am actually imposing some stricter condition
> on it ,so why should that be not allowed. I can never do any harm (as
> i see).
No, it can't in that case and of course that example is fine. So is:
int a;
void f(const int *ap);
f(&a);
gcc will not complain. The problem occurs when the const qualifier is
being "added" at anything more than the first level of indirection.
The classic example being passing a T ** value to a function that
expects a const T **.
The problem is that adding a const at this second level is not safe:
#include <stdio.h>
const char foo = 'X';
void f(const char **cpp)
{
*cpp = &foo;
}
int main(void)
{
char *cp;
f(&cp); /* not permitted */
*cp = '!';
printf("c = %c\n", foo);
return EXIT_SUCCESS;
}
The problem is to come up with a set of rules that allows safe
assignments and parameter passing whilst stopping all those that are
unsafe. The C committee opted for simple wording[1] that sometimes
forbids a case the is safe.
[1] Roughly: "the type pointed to by the LHS has all the qualifiers of
the type pointed to by the RHS" for assignment and the function
calling is the defined in terms of assignment.
<snip>
--
Ben.
thanks ben for the detailed explanation , silly me i did read this
some time back but forgot .
thanks
Mohan