Like Tree2Likes
  • 1 Post By grumpy
  • 1 Post By laserlight

Multi Arrays

This is a discussion on Multi Arrays within the C Programming forums, part of the General Programming Boards category; Well in both Dev C++ and Code::Blocks I get an error from the code below. I wrote the code as ...

  1. #1
    Registered User
    Join Date
    Sep 2013
    Location
    Jamaica
    Posts
    123

    Multi Arrays

    Well in both Dev C++ and Code::Blocks I get an error from the code below. I wrote the code as exact as possible like what I see in my book(C how to program 6th edition). Can some1 explain the reason for these warning messages?

    Code:
    #include <stdio.h>
    
    
    void printArray(const int a[][3]);
    
    
    int main(void)
    {
    	int array1[2][3] = {{1,2,3}, {4,5,6}};
    	int array2[2][3] = {1,2,3,4,5};
    	int array3[2][3] = {{1,2,}, {4}};
    	
    	printf("Values in array1 by row are:\n");
    	printArray(array1);
    	
    	printf("Values in array2 by row are:\n");
    	printArray(array2);
    	
    	printf("Values in array3 by row are:\n");
    	printArray(array3);
    	
    	return 0;
    }
    
    
    void printArray(const int a[][3])
    {
    	int i;
    	int j;
    	
    	for(i = 0; i <= 1; i++)
    	{
    		for(j = 0; j <= 2; j++)
    		{
    			printf("%d", a[i][j]);
    		}
    		printf("\n");
    	}
    }
    The warnings are:

    warning: passing argument 1 of 'printArray' from incompatible pointer type[enable by default]
    note: expected 'const int (*)[3]' but argument is of type 'int (*)[3]'

    shoes for each function calling

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,261
    It's an issue with const'ness. A pointer to an array of int is not convertible to a pointer to an array of const int.

    Prefix the definitions of array1 and array3 with const (before the int).

    The definition of array2 is a bit suspect too, since it is initialising a 2D array using a 1D array. That isn't strictly forbidden (which is why the compiler will accept it) but it is not a good idea either.
    SirPrattlepod likes this.
    Right 98% of the time, and don't care about the other 3%.

  3. #3
    11DE784A SirPrattlepod's Avatar
    Join Date
    Aug 2013
    Posts
    485
    In addition to grumpy's response, the "issue" is essentially the same as described here: Question 11.10

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by SirPrattlepod View Post
    In addition to grumpy's response, the "issue" is essentially the same as described here: Question 11.10
    I agree with this part: "The reason that you cannot assign a char ** value to a const char ** pointer is somewhat obscure."
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  5. #5
    11DE784A SirPrattlepod's Avatar
    Join Date
    Aug 2013
    Posts
    485
    Quote Originally Posted by oogabooga View Post
    I agree with this part: "The reason that you cannot assign a char ** value to a const char ** pointer is somewhat obscure."
    So do I actually

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by grumpy View Post
    It's an issue with const'ness. A pointer to an array of int is not convertible to a pointer to an array of const int.

    Prefix the definitions of array1 and array3 with const (before the int).
    Alternatively, if he didn't want his arrays to be const int, he could use a cast:
    Code:
        printArray((const int(*)[3])array1);
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  7. #7
    11DE784A SirPrattlepod's Avatar
    Join Date
    Aug 2013
    Posts
    485
    Quote Originally Posted by oogabooga View Post
    Alternatively, if he didn't want his arrays to be const int, he could use a cast:
    Code:
        printArray((const int(*)[3])array1);
    That's what I'd do but for some reason it makes me feel all yucky and doubtful.

    Edit: you can probably get away with

    Code:
        printArray((const int **)array1);
    but I'm not 100% sure at the moment

  8. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by SirPrattlepod View Post
    That's what I'd do but for some reason it makes me feel all yucky and doubtful
    It's ugly, that's for sure, but it seems justified in this case (as opposed to a symptom of bad design).
    Actually, I'd just leave the const off of the printArray argument in the first place.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,636
    Quote Originally Posted by oogabooga
    Actually, I'd just leave the const off of the printArray argument in the first place.
    But if you do that, then what happens if you have a const int array1[2][3]?

    One way out might be to wrap it in a struct:
    Code:
    struct array2d
    {
        int elements[2][3];
    };
    
    void printArray(const struct array2d *array);
    grumpy likes this.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,261
    Quote Originally Posted by oogabooga View Post
    Alternatively, if he didn't want his arrays to be const int, he could use a cast:
    Code:
        printArray((const int(*)[3])array1);
    I'd be cautious of that. While it's sometimes necessary, the problem with such a cast is that it can convert ANY type of array or pointer, whether that is valid or not.

    Generally, I treat any need for a typecast as a design problem. Usually, that's a sign of the design problem with the code in question. In this case, I consider it is actually a sign of a design problem with the language itself (and one for which there is not, as yet, a clean solution).

    However, it is rare, in practice, that one needs to pass a single argument to a function that is a multidimensional array with const qualifiers. For that reason, I like laserlight's suggestion - it avoids the obscure concerns about WHAT is actually const and what is not (and of equivalence between pointers and arrays), without the blunt instrument of a type conversion. And a struct can be used to package up other relevant data (in the sense of what the function might need to operate on the array) with the array.
    Right 98% of the time, and don't care about the other 3%.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. multi string arrays
    By nasser in forum C Programming
    Replies: 10
    Last Post: 09-12-2011, 01:20 PM
  2. multi-dimensional arrays
    By shuo in forum C++ Programming
    Replies: 7
    Last Post: 06-17-2008, 10:22 PM
  3. multi-dimensional arrays
    By maple23 in forum C Programming
    Replies: 4
    Last Post: 05-31-2008, 01:58 AM
  4. Multi-Arrays
    By KoG Metalgod in forum C Programming
    Replies: 7
    Last Post: 12-06-2006, 08:56 AM
  5. Multi-dimensional Arrays
    By thinhare in forum C Programming
    Replies: 9
    Last Post: 12-20-2004, 08:21 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21