Argument Incompatible With Parameter: Safe to ignore?

Thread Starter

TechWise

Joined Aug 24, 2018
151
I have written a function to accept an array of floats and then find the index of the minimum value:
Code:
int minimum(float * array, int size)
{
    float minimum = *array;
    int index = 0;
    int x = 0;
    for(x=0; x<size; x++)
    {
        if(*array < minimum)
        {
            minimum = *array;
            index = x;
        }
        array++;
    }
    return index;
}
Elsewhere, I declare the array and call the function. (Contents of "errors" are populated elsewhere. "index" is also declared elsewhere)
Code:
float errors[8];
index = minimum(&errors, 8);
As I understand it, when an array is passed to a function in C, it is actually a pointer to the first element that gets passed. However, my compiler is warning me that:
Code:
Description    Resource    Path    Location    Type
#169-D argument of type "float (*)[8]" is incompatible with parameter of type "float *"    control.c    /Two_Step_FCS_MPC/controlLogic    line 151    C/C++ Problem
Is this safe to ignore or am I actually doing something wrong? The code appears to function as I intended.
 

ZCochran98

Joined Jul 24, 2018
304
When you create an array in C, the array name (in your case, "errors") itself is a pointer. So saying "&errors" is telling the program "get me the pointer to the pointer to the first element of the array." Get rid of the "&," and it should work correctly and get rid of the compiler warning.

As a note, "errors[0]" is exactly equal to "*errors", and the statement "errors" is equivalent to to "*(errors+i)." So, in turn, "errors" is equivalent to "&(errors[0])."

Edit: for some reason the formatting decided to italicize things.
 

WBahn

Joined Mar 31, 2012
30,077
I have written a function to accept an array of floats and then find the index of the minimum value:
Code:
int minimum(float * array, int size)
{
    float minimum = *array;
    int index = 0;
    int x = 0;
    for(x=0; x<size; x++)
    {
        if(*array < minimum)
        {
            minimum = *array;
            index = x;
        }
        array++;
    }
    return index;
}
Elsewhere, I declare the array and call the function. (Contents of "errors" are populated elsewhere. "index" is also declared elsewhere)
Code:
float errors[8];
index = minimum(&errors, 8);
As I understand it, when an array is passed to a function in C, it is actually a pointer to the first element that gets passed. However, my compiler is warning me that:
Code:
Description    Resource    Path    Location    Type
#169-D argument of type "float (*)[8]" is incompatible with parameter of type "float *"    control.c    /Two_Step_FCS_MPC/controlLogic    line 151    C/C++ Problem
Is this safe to ignore or am I actually doing something wrong? The code appears to function as I intended.
You should never ignore warnings. They usually reveal something you've done that is a logic error or at least poor coding practice. If nothing else, their very presence makes it harder to spot the warnings that really must be corrected.

At the very least, if you are going to accept a warning, you should explore it well enough to be able to document why it is safe to ignore and why it is reasonable to not revise the code to make it go away. That's essentially what you are doing, so good for you.

The name of an array IS a pointer to the array.

Consider the following:

int myArray[3];
int *myPointer;

myPointer = myArray;

This only works because myArray is an expression that evaluates to the address where the array is stored -- it's in effect a pointer to the array. Which is exactly what myPointer is. So most places you can use one, you can use the other.

If you have &myPointer, the value that results is NOT a pointer to the array (i.e., the address in memory where the array starts), it is a pointer to the where myPointer is stored.

So you would expect &myArray to behave similarly -- it should be the address where the pointer myArray is stored.

But here's where things get a bit subtle. While we often say that myArray is a pointer, it isn't. It's a label. It is not stored in memory like a variable is and therefore has not address. Thus &myArray is not a clear concept. However, the C standard requires that it evaluate to the same thing as myArray, which is why your code runs successfully. I frankly don't know the reasoning behind why they specified this behavior and I rather wish they hadn't. I suspect there is some use case for which there is some utility that I am just not aware of.
 

Thread Starter

TechWise

Joined Aug 24, 2018
151
Thanks @ZCochran98 for this reply. I understand what is going on better now.

Thanks once again to @WBahn for another very detailed reply. Your last paragraph certainly explains why the code seems to work even though it's not "correct". Another snippet to add to my notes.
 
Top