Go Down

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

pYro_65

#30
Jul 13, 2016, 02:05 pm Last Edit: Jul 13, 2016, 02:07 pm by pYro_65
In spite of my smileys I did read your Reply.

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.
To mention it as an inconsistency, then to mention an explicit cast gives me reason to believe you did not understand my post.

I pointed out how C++ works, yes.

But I go on to use that to explain why arrays cast like that, so which ever way you want to describe it, I have covered it.

And to repeat very briefly, an array casts implicitly because it is the only way you can access elements (by using a pointer), so it makes sense to provide this implicitly.

...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.

You are asking why does an apple not taste like an orange, even though they are both fruit.

Fur is a trait of animals, a dog is an animal, but in no means does this imply that every animal is a dog, or every animal has fur...
Forum Mod anyone?
https://arduino.land/Moduino/

Robin2

#31
Jul 13, 2016, 07:31 pm Last Edit: Jul 13, 2016, 07:32 pm by Robin2
Biology is full of inconsistencies because evolution has neither a plan nor foresight. There is no reason why human creations (such as programming languages) have to have them.

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

pYro_65

Biology is full of inconsistencies because evolution has neither a plan nor foresight. There is no reason why human creations (such as programming languages) have to have them.

...R
There are no inconsistencies here. I'm confused as to why you trying so hard to connect two unrelated things.

Quote
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.
Write some pseudo code and see how your trail of thought does not really make sense. An array cast can not be applied to a 'simple' variable. For one, you need to use the address of operator to get the address of a variable. Casting it to a pointer gives you a pointer to somewhere, not a pointer to the variable.

Just rephrase your argument with another questionable statement: why can't I use the subscript operator with a simple variable ...Its inconsistent?

Well they may both be variables, but it'd be absurd to demand that a feature for arrays/pointers be available with things that have no use for them.

These aren't inconsistencies, its a flawed approach comparing two dissimilar things.

Two blueberry muffins, one with heaps of berries, and the other only has one. As the mixture was not mixed properly the muffins were inconsistent.

You cannot find an inconsistency between a brownie and a muffin, they are simply just different things. Saying your muffin is inconsistent because it does not look like a brownie is silly, but none the less, the same argument you are filing for arrays vs 'simple' variables.
Forum Mod anyone?
https://arduino.land/Moduino/

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

#35
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

#39
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

#42
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

#43
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.

Go Up