1

I want to pass a 2D array to a function, and the value of the array will not be modified in that function. So I am thinking about doing this way:

#include <Windows.h>

static INT8 TwoDimArrayConst(const INT8 ai_Array[2][2]);   

int main(void)
{
        INT8 ai_Array[2][2]       = { { { 1 }, { 2 } }, { { 3 }, { 4 } } };

  (void)TwoDimArrayConst(ai_Array);                           // Message 0432: [C] Function argument is not of compatible pointer type.

  return 1;
}

static INT8 TwoDimArrayConst(const INT8 ai_Array[2][2])
{
  INT8 test = 0;
  for (INT8 i = 0; i < 2; i++)
  {
    for (INT8 k = 0; k < 2; k++)
    {
      if (ai_Array[i][k] > 0)
      {
        test = 1;
      }
    }
  }
  if (test == 0)
  {
    test = 2;
  }

  return test;
}

However, it gave me the QAC error when I enabled depth 5 QAC setting as the one I put is the code comment above:

// Message 0432: [C] Function argument is not of compatible pointer type.

If I remove the const in the function declaration and definition, so the function is like:

static INT8 TwoDimArrayConst(INT8 ai_Array[2][2]);

this error will be gone, but there will be another error saying:

> The object addressed by the pointer parameter 'ai_Array' is not
> modified and so the pointer could be of type 'pointer to const'.

So how to resolve this dilemma? I cannot define ai_Array to be const array in the main fuction since some other function may still want to modify the value. Also, I am looking for the solution that still maintain the double brackets(no need to pass row size and column size as separate arguments) in the function, instead of treat it as a 1D array.

fuhuan26
  • 43
  • 5
  • "If I remove the `const` in the function call" ... do you mean, in the function _declaration_ and _definition_? Those are the only places I can see `const` in the code. – Tim Randall Feb 18 '19 at 17:43
  • yes, you are right. I just modify my question to make it less confusing. Thank you for pointing it out. @TimRandall – fuhuan26 Feb 18 '19 at 18:52

1 Answers1

1

the following proposed code:

  1. uses the C library functions rather than the windows functions, since I'm running on linux, not windows
  2. performs the desired functionality
  3. cleanly compiles
  4. takes advantage of arrays, in C, being laid out consecutively in memory
  5. takes advantage of "accessing an array name degrades to the address of the first byte of the array"
  6. removes all the unneeded braces (which are doing nothing but cluttering the code)
  7. documents why each header file is included
  8. passes the size of the array as an parameter to the called function (should always either do this or include some kind of 'marker' in the contents of the array)
  9. all the above allows treating the array as a 1 dimensional array
  10. breaks out of the loop in the called function as soon as the terminating condition is encountered

BTW: the header file: windows.h is not portable

and now, the proposed code:

//#include <Windows.h>
#include <stdio.h>    // printf()
#include <stdint.h>   // int8_t


static int8_t TwoDimArrayConst( const int8_t *ai_Array, size_t size );   

int main(void)
{
    const int8_t ai_Array[2][2]       = { { 1, 2 }, { 3, 4 }  };

    int8_t returnValue = TwoDimArrayConst(( int8_t* const )ai_Array, sizeof( ai_Array) / sizeof( int8_t ));                           

    printf( "%d\n", returnValue );
    return 1;
}


static int8_t TwoDimArrayConst( const int8_t *ai_Array, size_t size )
{
    int8_t test = 2;
    for ( size_t i = 0; i < size; i++)
    {
        if (ai_Array[i] > 0)
        {
            test = 1;
            break;
        }
    }

    return test;
}

A run of the proposed code results in:

1
user3629249
  • 16,402
  • 1
  • 16
  • 17
  • Thank you for the answer. The code looks very clean and is able to build. However,QAC still throws an error on line ` int8_t returnValue = TwoDimArrayConst((int8_t* const)ai_Array, sizeof(ai_Array) / sizeof(int8_t));` – fuhuan26 Feb 19 '19 at 14:21
  • It says "Casting to different object pointer type." Also, I saw const int8_t ai_Array[2][2], this is still defined as a const. I am looking for a way to define the array without const, but still pass to function as const without QAC warning. – fuhuan26 Feb 19 '19 at 15:45
  • what is `QAC`? If you do not want to declare the array as 'const' then just remove that modifier from the declaration of the array I.E. `int8_t ai_Array[2][2] = { { 1, 2 }, { 3, 4 } };` – user3629249 Feb 19 '19 at 19:26
  • OT: Note: placing a 'static' qualifier on a function signature is only useful if there are multiple files in the project and want the function to be hidden so other files can not access it – user3629249 Feb 19 '19 at 19:30
  • It is a static code analysis tool, PRQA Qa-C (there is a Qa-C++ as well). My company use it as the code guideline, need to remove all the QAC errors. – fuhuan26 Feb 19 '19 at 20:26
  • Some possibilities 1) create a union for the current array and an array of `int`, then pass the array of `int`. 2) add a typedef for the array then use the typedef in the definition of the array and in the sub function parameter, then inside the sub function, cast the resulting pointer as an array of `int`. However, IMO: a tool that declines good code is not a good tool. – user3629249 Feb 19 '19 at 20:35