This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Warning 167(-D) on const type * versus type *

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.