12 Replies - 515 Views - Last Post: 22 February 2013 - 08:27 AM Rate Topic: -----

#1 domenico  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 89
  • Joined: 21-July 12

[QUICK] Constant pointers. Ambiguos overload.

Posted 17 February 2013 - 04:44 AM

Hey guys,
I am trying to implement a simple function that reads a matrix from a file.
I can't understand why the instructions:
for ( int current = 0; current < COLS * ROWS; current++ )
		ifile >> *( first_el + current );

don't work if first_el is a constant pointer to a constant integer (const int * const ).
GCC doesn't compile and here is the log
error: ambiguous overload for 'operator>>' in 'ifile >> *(((const int*)first_el) + ((unsigned int)(((unsigned int)current) * 4u)))'


They work if first_el is a ( variable )pointer to a constant integer ( const int * )

This post has been edited by domenico: 17 February 2013 - 04:44 AM


Is This A Good Question/Topic? 0
  • +

Replies To: [QUICK] Constant pointers. Ambiguos overload.

#2 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2151
  • View blog
  • Posts: 3,307
  • Joined: 21-June 11

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 17 February 2013 - 05:29 AM

const int * is not a pointer to a const int - it's a const pointer to an int. A pointer to a const int would be int * const and that would cause the same error message as const int * const because, somewhat unsurprisingly, you're not allowed to write to a const int (whereas whether or not the pointer is const is entirely irrelevant when trying to write to where the pointer points).

This post has been edited by sepp2k: 17 February 2013 - 08:35 AM

Was This Post Helpful? 1
  • +
  • -

#3 domenico  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 89
  • Joined: 21-July 12

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 17 February 2013 - 05:52 AM

View Postsepp2k, on 17 February 2013 - 05:29 AM, said:

const int * is not a pointer to a const int - it's a const pointer to an int. A pointer to a const int would be int * const and that would cause the same error message as const int * const because, somewhat unsurprisingly, you're not allowed to write to a const int (whereas whether or not the pointer is const is entirely irrelevant when trying to write to where the pointer points).


Are you sure?
I actually noticed that const int * doesn't work.
int * const does.
That would suggest to me that the pointer's attribute is the last one.
Sorry for wrong reporting in the first post!

This post has been edited by domenico: 17 February 2013 - 05:53 AM

Was This Post Helpful? 0
  • +
  • -

#4 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2151
  • View blog
  • Posts: 3,307
  • Joined: 21-June 11

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 17 February 2013 - 05:59 AM

View Postdomenico, on 17 February 2013 - 01:52 PM, said:

Are you sure?


Yes. No, I'm talking bullshit.

You can enter the declarations on cdecl.org if you don't want to rely on my word insane ramblings (sadly cdecl only works with C types though - so it's of limited use when coding C++).

Quote

That would suggest to me that the pointer's attribute is the last one.


Right.

This post has been edited by sepp2k: 17 February 2013 - 08:36 AM

Was This Post Helpful? 1
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5907
  • View blog
  • Posts: 12,811
  • Joined: 16-October 07

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 17 February 2013 - 06:09 AM

You kind of have to read them backwards:
int * const -  const pointer to int
int const * -  pointer to const int
const int * -  same as "int const *".  yep, that's confusing



You can write a simple program to test your assumptions of course. In such a case, it's more about what the compiler believes than what you do. ;)
Was This Post Helpful? 1
  • +
  • -

#6 domenico  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 89
  • Joined: 21-July 12

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 17 February 2013 - 08:21 AM

View Postsepp2k, on 17 February 2013 - 05:59 AM, said:

View Postdomenico, on 17 February 2013 - 01:52 PM, said:

Are you sure?


Yes. You can also enter the declarations on cdecl.org if you don't want to rely on my word (sadly cdecl only works with C types though - so it's of limited use when coding C++).

Quote

That would suggest to me that the pointer's attribute is the last one.


Right.


Contraddiction here!

Anyway, thank you for the url! Didn't know about cdecl.org, it's very useful for a beginner.
Was This Post Helpful? 0
  • +
  • -

#7 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2151
  • View blog
  • Posts: 3,307
  • Joined: 21-June 11

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 17 February 2013 - 08:37 AM

View Postdomenico, on 17 February 2013 - 04:21 PM, said:

Contraddiction here!


Yes, sorry, I managed to thoroughly confuse myself. All clear now.

This post has been edited by sepp2k: 17 February 2013 - 08:37 AM

Was This Post Helpful? 0
  • +
  • -

#8 domenico  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 89
  • Joined: 21-July 12

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 19 February 2013 - 02:42 PM

hey guys, another question strictly related to this so i'm gonna post it here.

I get this error from g++
error: invalid conversion from 'int**' to 'const int**' [-fpermissive]
error: initializing argument 1 of 'void printMatrix(const int**, int, int)' [-fpermissive]
when I try to pass a matrix of integers to a functions.
I do not want the integer to be edited by the called function ( it's a print function ) so I pass them as constant valuees.
Why the compiler wouldn't allow me to do that?

This post has been edited by domenico: 19 February 2013 - 02:42 PM

Was This Post Helpful? 0
  • +
  • -

#9 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2151
  • View blog
  • Posts: 3,307
  • Joined: 21-June 11

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 19 February 2013 - 04:03 PM

const int** means "non-const pointer to non-const pointer to const int". This means that the integers can't be changed, but the inner pointers can. So if I have a function f(const int** p), it would be legal for that function to do something like *p = different_pointer;. Now here's an example where passing in an int** to such a function would destroy const correctness:

const int my_const_array[] = {1,2,3};

void f(const int** p) {
  *p = my_const_array;
}

void my_function() {
  int row1[] = {4,5,6};
  int row2[] = {7,8,9};
  int* arr[] = {row1, row2};
  f(arr);
  arr[0][0] = 42; 
}



In the last line I'm changing the value of arr[0][0]. Since nothing about arr is const, I'm perfectly allowed to do that. However arr[0] is currently my_const_array, which is const. So I'm mutating a const array, which is illegal.

Basically passing a non-const pointer as a const-pointer is only safe if the consts are added from the outside-in. That is it's okay to call a function with a pointer to non-const pointer to non-const if the function takes a pointer to const-pointer to non-const int or if it takes a pointer to const-pointer to const int, but not if it takes a pointer to non-const pointer to const-int.

So in your case the best solution would be to simply make both the rows and the integer of your matrix const like this:

void printMatrix(const int* const*, int, int)

This post has been edited by sepp2k: 19 February 2013 - 04:04 PM

Was This Post Helpful? 1
  • +
  • -

#10 domenico  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 89
  • Joined: 21-July 12

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 21 February 2013 - 01:57 PM

View Postsepp2k, on 19 February 2013 - 04:03 PM, said:

const int** means "non-const pointer to non-const pointer to const int". This means that the integers can't be changed, but the inner pointers can. So if I have a function f(const int** p), it would be legal for that function to do something like *p = different_pointer;. Now here's an example where passing in an int** to such a function would destroy const correctness:

const int my_const_array[] = {1,2,3};

void f(const int** p) {
  *p = my_const_array;
}

void my_function() {
  int row1[] = {4,5,6};
  int row2[] = {7,8,9};
  int* arr[] = {row1, row2};
  f(arr);
  arr[0][0] = 42; 
}



In the last line I'm changing the value of arr[0][0]. Since nothing about arr is const, I'm perfectly allowed to do that. However arr[0] is currently my_const_array, which is const. So I'm mutating a const array, which is illegal.

Basically passing a non-const pointer as a const-pointer is only safe if the consts are added from the outside-in. That is it's okay to call a function with a pointer to non-const pointer to non-const if the function takes a pointer to const-pointer to non-const int or if it takes a pointer to const-pointer to const int, but not if it takes a pointer to non-const pointer to const-int.

So in your case the best solution would be to simply make both the rows and the integer of your matrix const like this:

void printMatrix(const int* const*, int, int)


So, if I understood correctly in the statement
 const int* const* const MATRIX; 

the first const is referred to the integer, the second const to the pointers pointed by matrix ( the pointers that point to the first element of each column ) and the last const is reffered to the pointer MATRIX. Is that right?
If so, isn't that safer than const int * const * when allowed to pass that ( i.e. printing a matrix )?
Was This Post Helpful? 0
  • +
  • -

#11 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2151
  • View blog
  • Posts: 3,307
  • Joined: 21-June 11

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 21 February 2013 - 02:37 PM

View Postdomenico, on 21 February 2013 - 09:57 PM, said:

So, if I understood correctly in the statement
 const int* const* const MATRIX; 

the first const is referred to the integer, the second const to the pointers pointed by matrix ( the pointers that point to the first element of each column ) and the last const is reffered to the pointer MATRIX. Is that right?


Yes, that's right.

Quote

If so, isn't that safer than const int * const * when allowed to pass that ( i.e. printing a matrix )?


Whether or not the MATRIX pointer itself is const or not doesn't really matter because MATRIX is a local variable (which really shouldn't be capitalized like that - the convention in C and C++ is to use ALL_CAPS only for #defines) and thus any changes to it will not be visible on the outside. That is if you reassign matrix, that will not in any way affect the pointer that you passed in to print_matrix.

PS: This isn't really related to your question, but might I suggest using a vector of vectors for your matrix and then passing that by const reference rather than using pointers? That will get rid of all this complexity in one swoop.
Was This Post Helpful? 0
  • +
  • -

#12 domenico  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 89
  • Joined: 21-July 12

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 22 February 2013 - 07:58 AM

Whether or not the MATRIX pointer itself is const or not doesn't really matter because MATRIX is a local variable (which really shouldn't be capitalized like that - the convention in C and C++ is to use ALL_CAPS only for #defines) and thus any changes to it will not be visible on the outside. That is if you reassign matrix, that will not in any way affect the pointer that you passed in to print_matrix.

I see, but passing matrix as a const, would let me recognize errors regarding bad assignments at the root because the compiler won't let me execute the code.

I capitalize every const in my code. Another way to express them I've seen often is to place a k before the name of the constant ( i.e. kRows, kCols ) but I found it to be really stressing (i use underscores in variable naming and applying that rule would result in k_rows, k_cols, etc...)
Do you find unnecessary expressing constant in a different way in your code?
If not, what convention do you like most?
Was This Post Helpful? 0
  • +
  • -

#13 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3652
  • View blog
  • Posts: 11,421
  • Joined: 05-May 12

Re: [QUICK] Constant pointers. Ambiguos overload.

Posted 22 February 2013 - 08:27 AM

Having spent many years writing Windows code, I'm used to seeing/using the 'c' or 'c_' prefix in Hungarian notation. http://en.wikipedia....garian_notation
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1