We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have a sourcecode like:
typedef int tQ32_16; typedef tQ32_16 tVector3[3];
tQ32_16 Length_V3(const tVector3 * vec) {....;}
void anyfunc(void) {
tVector3 v1 = {1,2,3}; tQ32_16 l1;
l1 = Length_V3(&v1); //==>> warning: #167-D: argument of type "tVector3 *" is incompatible with parameter of type "const tVector3 *"
.... }
Why do I get this warning ?? As far as I know this is correct C-code....
Compiles fine here. You must have omitted significant details when posting your code.
I just created a NEW uVision project (MDK-ARM Professional v4.50)
TARGET: NXP LPC1313, everyting else just default.
and added just the following code (main.c):
typedef int tQ32_16; typedef tQ32_16 tVector3[3]; tQ32_16 Length_V3(const tVector3 * vec) { tQ32_16 result = (*vec)[0]; return result; } int main(void) { tVector3 v1 = {1,2,3}; tQ32_16 l1; l1 = Length_V3(&v1); return l1; }
And when I compile I get the following output:
Build target 'Target 1' compiling main.c... main.c(17): warning: #167-D: argument of type "tVector3 *" is incompatible with parameter of type "const tVector3 *" main.c: warning: #167-D: argument of type "tVector3 *" is incompatible with parameter of type "const tVector3 *" linking... warn167_test.axf: Error: L6218E: Undefined symbol SystemInit (referred from startup_lpc13xx.o). Target not created
Oops, I used IAR compiler. But the warning does look odd.
I don't think so.
Look again at the message: it tells you two things are not compatible; so look at those two things, consider the difference(s) between them, and think why that would make them "not compatible"...
Sorry Andrew, but as far as I can see the message tells me just ONE difference and that is the "const". ("tVector3 *" and "const tVector3 *").
And there is nothing wrong in passing a (not const) variable as a const parameter since the const in the parameter list just tells that the function won't change the value pointed to....
The other way around however would be incompatible since a not const parameter would mean that the function could change the value pointed to, so you can't pass a const variable in this case...
Passing the code snippet through the gimpel-lint online checker produced:
FlexeLint for C/C++ (Unix/386) Vers. 9.00i, Copyright Gimpel Software 1985-2012 --- Module: intro.txt (C) 1 typedef int tQ32_16; 2 typedef tQ32_16 tVector3[3]; 3 4 tQ32_16 Length_V3(const tVector3 * vec) 5 { 6 tQ32_16 result = (*vec)[0]; 7 8 return result; 9 } 10 11 int main(void) 12 { 13 tVector3 v1 = {1,2,3}; 14 tQ32_16 l1; 15 _ 16 l1 = Length_V3(&v1); intro.txt 16 Warning 545: Suspicious use of & 17 18 return l1; 19 }
The warning message stated:
Suspicious use of & -- An attempt was made to take the address of an array name. At one time such an expression was officially illegal (K&R C [1]), was not consistently implemented, and was, therefore, suspect. However, the expression is legal in ANSI C and designates a pointer to an array. For example, given int a[10]; int (*p) [10]; Then a and &a, as pointers, both represent the same bit pattern, but whereas a is a pointer to int, &a is a pointer to array 10 of int. Of the two only &a may be assigned to p without complaint. If you are using the & operator in this way, we recommend that you disable this message.
Besides this has nothing to do with the original problem..... this is ALSO an unjust warning !!
Look at the code !: v1 IS an array, and the parameter IS a POINTER to array !!! so &v1 is a 100% correct syntax.
And as the warning itself states: "Of the two only &a may be assigned to p without complaint" so why is it complaining ?
this is ALSO an unjust warning !!
Hmmm. You might get some disagreement on that one.
But anyway:
The reason I showed you this is precisely because it does not show anything concerning your original problem; and nor do a couple of other compilers I tried. So it suggests that maybe Keil is either being over-zealous or (horror of horrors) is wrong.
Maybe someone who obviously sees what is wrong and chooses not to say should actually back up their statement.
I think I got it. What you really want to write is the following:
typedef int tQ32_16; typedef tQ32_16 tVector3[3]; tQ32_16 Length_V3(const tVector3 vec) { tQ32_16 result = vec[0]; return result; } int main(void) { tVector3 v1 = {1,2,3}; tQ32_16 l1; l1 = Length_V3(v1); return l1; }
The type tVector3 is an array. Arrays are passed to function by reference. So in essense the type of the argument is now const int* vec. In your original code it was const int** vec which doesn't make much sense.
Mike, Thanks.
Sorry for my very limited C skill. Just want to know if my understanding is correct or not.
#include <stdio.h> int Length_V3( int vec[][3] ) { int result = vec[0][0]; return result; } int main(void) { int v1[1][3] = { { 0xA, 0xB, 0xC } }; int l1; l1 = Length_V3(&v1[0]); printf( "l1 = %X", l1 ); return 0; }
Tested with X86/WinXP/Code::Blocks 10.05
Compiling: C:\WINDOWS\Temp\main_b.c Linking console executable: C:\WINDOWS\Temp\main_b.exe Process terminated with status 0 (0 minutes, 0 seconds) 0 errors, 0 warnings
l1 = A Process returned 0 (0x0) execution time : 0.016 s Press any key to continue.