Pointers

I have a question about the code below. In the function myTest(), there are two ways of setting the value of thisTest. The active one (not remarked out) will print the address of testInt. The one remarked out will print the value stored in testInt. Is that correct?

void setup()
{
  pinMode(13,OUTPUT);
  Serial.begin(9600);
}

void myTest(int *testInt)
{
  int thisTest = (int)testInt;
// int thisTest = *testInt;
  Serial.print("Value ");
  Serial.println(thisTest,DEC);  
}

void loop()
{
  int myInt = 4;
  
  digitalWrite(13,HIGH);
  delay(500);
  digitalWrite(13,LOW);
  delay(500);  
  myTest(&myInt);
}

The active one (not remarked out) will print the address of testInt. The one remarked out will print the value stored in testInt. Is that correct?

Yes. To be technically accurate, though, the second one will print the value in the memory address that testInt points to.

Thanks. That is what I had presumed. The first prints the address, the second prints the value 4. That is why I really don't understand this. I put a remark above the questionable statement.

void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
{
  uint16_t ptr;
  ptr = readSnRX_RD(s);
  read_data(s, (uint8_t *)ptr, data, len);
  if (!peek)
  {
    ptr += len;
    writeSnRX_RD(s, ptr);
  }
}

void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
{
  uint16_t size;
  uint16_t src_mask;
  uint16_t src_ptr;

// this puts the address of ptr into src_mask, not the value. Is that correct? Passed as a pointer to this function.
  src_mask = (uint16_t)src & RMASK;
  src_ptr = RBASE[s] + src_mask;

  if( (src_mask + len) > RSIZE ) 
  {
    size = RSIZE - src_mask;
    read(src_ptr, (uint8_t *)dst, size);
    dst += size;
    read(RBASE[s], (uint8_t *) dst, len - size);
  } 
  else
    read(src_ptr, (uint8_t *) dst, len);
}

I put a remark above the questionable statement.

There is a difference between what & means in a variable declaration and what it means in a line of code. In a variable definition in a function declaration, it means address of. In code, as in the line you refer to, it means bitwise and - something completely different.

http://arduino.cc/en/Reference/BitwiseAnd

Exactly. It is bitwise ANDing the ADDRESS of ptr in the calling function with the mask, not the value as I expected. Is that part correct?

Exactly. It is bitwise ANDing the ADDRESS of ptr in the calling function with the mask, not the value as I expected. Is that part correct?

No. In the caller:

  uint16_t ptr;
  ptr = readSnRX_RD(s);
  read_data(s, (uint8_t *)ptr, data, len);

The variable prt is cast to a pointer. The cast succeeds because ints and pointers are the same size. This is done so that the called function can modify the value in the memory space that ptr is bound to.

In the called function, the value in that memory space is what is being operated on, not the address of the memory space.

Yes. I understand that. It gets to the called function fine. As an address to ptr.
It is this I don’t understand.

src_mask = **(uint16_t)**src & RMASK;

This would bitwise AND the address of ptr with the mask.

Shouldn’t that be

src_mask = (uint16_t *)src & RMASK;

This would bitwise AND the value in ptr, correct?

Thanks for your help. It is appreciated. :slight_smile:
Please excuse my sometimes simple questions. I am trying to find a bug in code I am not that familiar with.

EDIT: This code is from w5100.cpp

This would bitwise AND the address of ptr with the mask.

No. The value that was passed to the function was not an address. The function expects an address, so the value was cast as a pointer, so that it could be passed to the function. Casting something as a pointer doesn't make it a pointer.

I just did a little experimenting, and you are right. Casting something does not make it something.

When you cast ptr as a pointer in the function call, rather than sending the address of ptr (&ptr), it does not make it an address, so you cannot modify the value in ptr from the called routine. I just tried.

EDIT: It seems to get the correct value there, but why not just pass it as (uint16_t). ?? There is no write reference to "src", so it doesn't modify it from the called routine.