-1

I'd written a tiny c program. The code compiled successfully by GCC 4.8.5 20150623 (Red Hat 4.8.5-4) with -std=c99, but gave me a warning. I cannot deal with the warning, and I even don't known what's wrong with it. The code is here:

#include <stdio.h>
#define COLS 4
int SumOf2DArray(const int array[][COLS], int rows);
int SumOfArray(const int array[], int element_number);
int main(void) {
  int sum_of_array0, sum_of_2d_array, sum_of_array1;
  int *array, (*dimensions)[COLS];
  array = (int [2]){10, 20};
  dimensions = (int [2][COLS]){{1, 2, 3, -9}, {4, 5, 6, -8}};
  sum_of_array0 = SumOfArray(array, 2);
  sum_of_2d_array = SumOf2DArray(dimensions, 2);
  sum_of_array1 = SumOfArray((int []){4, 4, 4, 5, 5, 5}, 6);
  printf("sum_of_array0 = %d \t sum_of_2d_array = %d \t sum_of_array1 = %d\n",
    sum_of_array0, sum_of_2d_array, sum_of_array1);
  return 0;
}
int SumOf2DArray(const int array[][COLS], int rows) {
  int sum_of_2d_array = 0;
  for (int rows_i = 0; rows_i < rows; rows_i++) {
    for (int cols_i = 0; cols_i < COLS; cols_i++) {
      sum_of_2d_array += array[rows_i][cols_i];
    }
  }
  return sum_of_2d_array;
}
int SumOfArray(const int array[], int element_number) {
  int sum_of_array = 0;
  for (int i = 0; i < element_number; i++) {
    sum_of_array += array[i];
  }
  return sum_of_array;
}

And the warning is here:

chapter10_compound_literals.c: In function ‘main’:
chapter10_compound_literals.c:25:3: warning: passing argument 1 of ‘SumOf2DArray’ from incompatible pointer type [enabled by default]
   sum_of_2d_array = SumOf2DArray(dimensions, 2);
   ^
chapter10_compound_literals.c:15:5: note: expected ‘const int (*)[4]’ but argument is of type ‘int (*)[4]’
 int SumOf2DArray(const int array[][COLS], int rows);

Now, I assume I have a 2d-array: int array[2][3] = {{1, 2, 3}, {3, 4, 5}}, and I have a function: int SumOf2DArray(const int array[][3], int rows).

The way in the code above is using a pointer(int (*pointer)[3] = array), but get a warning, and I have tried to pass argument using array directly, but the same warning.

How I can pass the array to the function?

1 Answers1

-1

I think the answer is most clearly spelled out in the compiler output:

expected ‘const int (*)[4]’ but argument is of type ‘int (*)[4]’

Type int is, in fact, quite different from const int. Your code can be considered to have a bug if you try to change any const (eg assign to it), but obviously you can change int. My recommendation would be don't use const unless you know what you are doing--which may require some study, since const becomes complicated as types become complicated.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
Mike Layton
  • 93
  • 1
  • 6
  • Thanks for your answer. I have modified `SumOF2DArray()` to int SumOf2DArray(int array[][COLS], int rows); and the warning disappeared. However, this is not what i want. The `SumOF2DArray()` will not change value of `array[][COLS]`, so i think it's a good style to add `const` in the function. what make me confused is that the `SumOfArray()` also has a `const`, but no warning. – Yurk Tonxylor Aug 23 '16 at 02:33
  • well, you've identified the line with the problem, but your explanatory paragraph doesn't really have anything to do with the question. The code does not attempt to change any const ints – M.M Aug 23 '16 at 07:14
  • As I understood the question, the "problem" was the compiler warning, not the behavior of the program. Therefore, I consider the behavior of the program to be off topic. (Of course all programmers want to make sure their programs behave correctly all the time, so I don't need to remind of that, do I?). That said, the way the code is "fixed" to not generate the warning shouldn't change the results. In general, dropping const will never do that unless there is some other bug--it may affect performance/footprint. – Mike Layton Aug 23 '16 at 21:41
  • As for the question about keeping const in the code where it applies, the answer is kind of obvious at this point (at least the short answer). If you want a procedure to operate on a const, then pass it a const. (I don't think it makes sense to cast a non-const to a const, but maybe a compiler can be tricked into doing that. – Mike Layton Aug 23 '16 at 21:46
  • Even so, that sounds like a terrible idea to me. Note that the way you code the type of a variable is quite different from how you actually use it. I could code a boolean as a float and assign it to 0/1 and check it for being greater or less than 0.5. That would most likely be stupid, but the code would work. You can change a non-const or not according to what the code should do. You can pass a parameter and not use it. What you can't do is pretend that a const and a non-const are the same type. – Mike Layton Aug 23 '16 at 21:46
  • Reading the "already answered" question tells me that there is a great deal of interest in esoteric discussion of specific compiler capabilities and little interest in developing good beginning programmer skills. Anyone who suggests that a "compiler" can/should be able to cast from non-const to const, needs to be able to explain what that would entail. Much more than compiling code, for sure. – Mike Layton Aug 23 '16 at 22:09
  • Actually, `const` should have been the default. – Lightness Races in Orbit Oct 22 '16 at 01:29