Go Down

Topic: "Pointers make my head spin" etc ... (Read 4322 times) previous topic - next topic

Robin2

An array cast can not be applied to a 'simple' variable.
We are on different wavelengths.

Let's agree to disagree.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pYro_65

We are on different wavelengths.

Let's agree to disagree.
Nah, nothing is learned that way.

I was hoping you'd pick it up, but if you are really determined to argue that it is wrong for a simple variable to not be converted to a pointer, then you can stop looking at arrays, and focus on pointer arithmetic. Then you'll see how your argument is invalid.

Quote
I know that an array will cast to a pointer. What I don't understand is why a simple variable will not also cast to a pointer?
...
it makes even less sense for the compiler not to also cast an ordinary variable name to a pointer when it is "used in an expression that accepts a pointer as an operand"
This doesn't work like an int array would, no implicit cast (and really why should there be, it doesn't make sense).

int i = 4;
int *ptr = i;


But use an int in pointer arithmetic... and, well, the result is a pointer!

int i;
int *ptr;

int *ptr2 = ptr + i;


None the less, an integer cannot cast to a pointer implicitly when used in the circumstances an array can be used, but this is due to them being completely different things (apples/oranges).

Simple! No wires crossed, different wavelengths, or language barriers, just pure analysis of the facts.

Forum Mod anyone?
https://arduino.land/Moduino/

Robin2

#32
Jul 14, 2016, 06:48 pm Last Edit: Jul 14, 2016, 06:50 pm by Robin2
I am coming at this from a very basic position. Have a look at this snippet (I hope my syntax is correct)

Code: [Select]
byte myArray[1];
myArray[0] = 5;

byte myVar = 5;

 
In both cases there is a memory location at an address and it contains the number 5.

If I want to use this function call
bool RF24::write( const void * buf, uint8_t len)
I can do it like this
Code: [Select]
myRF24.write(myArray, 1);
or
Code: [Select]
myRF24.write(&myVar, 1);
(again I hope I have the syntax correct - I have only used the other version)

I cannot for the life of me see why C/C++ was designed in such a way that these things need to be treated differently.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Whandall

I can do it like this
Code: [Select]
myRF24.write(myArray, 1);
or
Code: [Select]
myRF24.write(&myVar, 1);
(again I hope I have the syntax correct - I have only used the other version)

I cannot for the life of me see why C/C++ was designed in such a way that these things need to be treated differently.
I think it is treated the same way, because
Code: [Select]
myRF24.write(myArray, 1);is only a shortcut for
Code: [Select]
myRF24.write(&myArray[0], 1);
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Robin2

I think it is treated the same way, because
Code: [Select]
myRF24.write(myArray, 1);is only a shortcut for
Code: [Select]
myRF24.write(&myArray[0], 1);
OK. Then my question is why didn't they make it so that the same shortcut works with the simple variable myVar? (i.e. so the & is not needed)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Whandall

There is no shortcut in the myVar case, because there is no myVar[0].
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

pYro_65

#36
Jul 15, 2016, 07:05 am Last Edit: Jul 15, 2016, 07:07 am by pYro_65
OK. Then my question is why didn't they make it so that the same shortcut works with the simple variable myVar? (i.e. so the & is not needed)
This has been covered fairly extensively above, but to summarize:

Quote
the standard conversion for arrays is needed to access array elements. This is because the subscripting operator works with pointers (not actually an array specific operator)

Quote
The expression E1[E2] is identical (by definition) to *((E1)+(E2))
Its identical form (second one listed above) shows that either E1 or E2 must be a pointer as it is dereferenced to access the value.

The code below is accessing the second element of the array two different ways using the subscripting operator, showing that at least one operand must be a pointer:


Code: [Select]
int array[5];

  int a = array[1];

  int b = 1[array];


So even though an implicit array to pointer conversion may seem strange, it is in fact needed to access elements of arrays.
...
An array is unrelated to 'ordinary' variables, and it has its own features just as primitive types have their own standard "integral conversions".
...
And why does an 'int' not do casting like this by default? Well that is because it does not make sense, is illogical, and is unrelated to an array.
...
There are no inconsistencies here. I'm confused as to why you trying so hard to connect two unrelated things.
...
These aren't inconsistencies, its a flawed approach comparing two dissimilar things.
And one more to the pile from Whandall:

Quote
There is no shortcut in the myVar case, because there is no myVar[0].
So as you can see, there is no array logic in 'simple' variables, because they aren't arrays. The array functionality is there because it is required, as I have mentioned above.

Your shortcut that you cannot understand why it isn't available to a standard variable makes no sense, why, because the choice is ambiguous: Do you return a pointer, or the actual int. With an array id (without subscript) all you have is a pointer to the first element, as an array reference and array pointer are not compatible and ignored.

Forum Mod anyone?
https://arduino.land/Moduino/

Robin2

Your shortcut that you cannot understand why it isn't available to a standard variable makes no sense, why, because the choice is ambiguous: Do you return a pointer, or the actual int. With an array id (without subscript) all you have is a pointer to the first element, as an array reference and array pointer are not compatible and ignored.
Thanks.

That makes some sense.

It has taken a long time :) :)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pYro_65

Thanks.

That makes some sense.

It has taken a long time :) :)

...R
lol, glad to be of service.
Forum Mod anyone?
https://arduino.land/Moduino/

Robin2

#39
Jul 15, 2016, 11:31 pm Last Edit: Jul 15, 2016, 11:34 pm by Robin2
On further reflection I think I still have the same problem.

Based on your explanation I can understand why there is a need to use &myVar so as to make it clear that it is the address that is needed rather than the value.

However if the system was consistent you would also be required to use &myArray when you want the address of the array. Using myArray with neither an & nor a subscript should cause an error.

(Keep in mind that this is a language that prides itself on being pernickety)

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pYro_65

#40
Jul 16, 2016, 04:28 am Last Edit: Jul 16, 2016, 04:46 am by pYro_65
However if the system was consistent you would also be required to use &myArray when you want the address of the array. Using myArray with neither an & nor a subscript should cause an error.
That is how you get an address of an array!

But that is the problem, it is a pointer to an array not a pointer to the first element. If you used a subscript operator like (&myArray)[3] you are attempting to access an array of arrays. Each index moves the pointer the length of the entire array - and is valid in some circumstances (multidimensional arrays).

The biggest point to mention here is 'myArray' is not returning a pointer to the variable, but an element - a closed concept only for arrays. '&myArray' and '&myInt' are both returning pointers to the variable you are using. Which is consistent use of the address-of operator.

If you dereference the pointer returned by '&myArray' and '&myInt' you return to the original variable. Whereas dereferencing the pointer provided by 'myArray' you get a reference to an element, which has nothing to do with the array.

If the rules you mentioned were in place, there would be no way to access the elements of a variable without some ugly code which converts the array pointer to a primitive pointer, then using pointer arithmetic to move along raw bytes.

((char*)(&myArray))[ 4 ];

This method is quite ugly, and breaks the strict typing elements. It allows you to completely disregard the type of the array, and has no size information associated with it. The array might not even be a char type.

And as for consistency, the way array's are accessed in C++ is consistent with 90% of other languages that use arrays. The parts that differ are because C++ has the concept of pointers, which many languages do not.

Another point is in reality, 'myArray' and 'myInt' are both expressions returning a reference to themselves. I think what you were saying is inconsistent, is actually there, it is just not as obvious. The code below shows this:

Code: [Select]
  int array[10];
  int (&arrRef)[10] = array;

  int value;
  int &valRef = value;


The reason why an array can cast is because it has a built in conversion. This concept can be described with a struct:

The code below will not work because a pointer and object are not compatible.

Code: [Select]
struct Foo{
  char *ptr;
};

void setup() {

  Foo foo;
  char *ptr = foo;
}

void loop(){}


However adding a conversion operator, like what arrays have built in, then it can:

Code: [Select]
struct Foo{
  //Conversion operator
  operator char*(){ return ptr; }
  char *ptr;
};

void setup() {

  Foo foo;
  char *ptr = foo;
}

void loop(){}


Forum Mod anyone?
https://arduino.land/Moduino/

Robin2

And, after a good night's sleep I am less convinced of the logic in the piece I quoted in Reply #40.

I don't really see why the choice would be ambiguous - why would I want the address of a simple variable? If it is a simple variable just assume I want the value.

There could be a special "add on" for those folks who really do want the address of a simple variable.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pYro_65

#42
Jul 16, 2016, 10:38 am Last Edit: Jul 16, 2016, 10:53 am by pYro_65
I don't really see why the choice would be ambiguous - why would I want the address of a simple variable? If it is a simple variable just assume I want the value.
Exactly! That is what happens now.


You were originally asking:

Quote
I know that an array will cast to a pointer. What I don't understand is why a simple variable will not also cast to a pointer?
You have answered this yourself: "why would I want the address of a simple variable? If it is a simple variable just assume I want the value.".

And if you checkout the two lines above the first code box in my last post, you'll see that this behavior is consistent!
------------------------------------
The ambiguity I mentioned would happen if a variable could return a value, or pointer when used in a pointer expression. This is because a pointer and a pointer can be added together (pointer arithmetic), but a pointer and an integral type can also be added together - so if the conversion you proposed was introduced, which one do you use... the pointer or value?

This is not the case with an array as only the pointer conversion is compatible. An array type cannot be cast to any other type except a reference to its own type. The ambiguity appears when there are two or more conversions which are compatible with the type being converted to (C++ is allowed to implicitly cast once for anything if there is an appropriate conversion available).
Forum Mod anyone?
https://arduino.land/Moduino/

Robin2

#43
Jul 16, 2016, 12:52 pm Last Edit: Jul 16, 2016, 12:53 pm by Robin2
See Reply #33   :)

We have wasted enough bandwith and server storage on this.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

pYro_65

#44
Jul 16, 2016, 01:32 pm Last Edit: Jul 16, 2016, 01:35 pm by pYro_65
See Reply #33   :)

We have wasted enough bandwith and server storage on this.

...R
Hmmm, it doesn't seem like you really know what you are trying to explain.

Why don't you do a big favor and justify these two statements you have made, then possibly your other wavelength may come to light:

Quote
I know that an array will cast to a pointer. What I don't understand is why a simple variable will not also cast to a pointer?
and

Quote
why would I want the address of a simple variable? If it is a simple variable just assume I want the value.
?????? Seriously what is going on, I'm quite intrigued!


All of your posts repeat the same thing over and over, then you answer your own question. If you wrote the wrong thing, this isn't a different wavelength, it is bad communication.

Why don't you try and explain what your gripe is in more than two sentences.
Or if you are waiting for people to simply agree with you, regardless of how many logical explanations are put forward, then you are simply just trolling (in which case you don't really agree with what you are writing).

Don't worry about bandwidth, the forum admin certainly don't, did you know that an open forum page checks for new alerts every 10 seconds. Multiply this by everyone online, and a few posts really are insignificant.

I would really like to know what the hidden meaning is in your quotes:

Quote
However if the system was consistent you would also be required to use &myArray when you want the address of the array. Using myArray with neither an & nor a subscript should cause an error.
Answered here

Quote
OK. Then my question is why didn't they make it so that the same shortcut works with the simple variable myVar? (i.e. so the & is not needed)
Answered here & here & here

Quote
I know that an array will cast to a pointer. What I don't understand is why a simple variable will not also cast to a pointer?
...
it makes even less sense for the compiler not to also cast an ordinary variable name to a pointer when it is "used in an expression that accepts a pointer as an operand"
Answered here & here & here & by yourself

Quote
I think the difference between us is that you are describing HOW C/C++ works whereas I am asking WHY does it work like that (because it seems to me to be inconsistent).

Another way that this "inconsistency" could be avoided would be if it was necessary to do an explicit cast to a pointer for an Array as well as for a simple variable.
And this is answered in pretty much every post in response to your questions. The reasons explaining this contain both how C++ works and why it works this way. I have also explained the consequences of why it wouldn't work if things were how you'd prefer.

Simply, what you would like to see, you yourself have given a reason as to why adding the functionality you would like is silly regardless of how consistent you think it could be.  And I have given compelling evidence as to why things wouldn't work if we removed what you don't like.

Forum Mod anyone?
https://arduino.land/Moduino/

Go Up