0

I'm writing the folowing function:

void SPI_TransmitReceive(const uint8_t* txbuf, uint8_t* rxbuf, size_t size);

And calling it with the same buf for tx and rx:

uint8_t mybuf[200];
SPI_TransmitReceive(mybuf, mybuf, 200);

Will there be an undefined behavior?

UPD: To clarify the question. Assume that:

void SPI_TransmitReceive(const uint8_t* txbuf, uint8_t* rxbuf, size_t size) {
    std::memmove(rxbuf, srcbuf, size);
}

cppreference says that memmove may lead to UB if regions are overlapping. Is it a typo?

  • 3
    That is up to the specification of that function. What does its documentation say? (My feeling is that it is unlikely to support that.) – user17732522 Oct 03 '22 at 17:32
  • How can we possibly know that without seeing that function's body/implementation/documentation? – Jason Oct 03 '22 at 17:32
  • If you actually mean that you are writing the function yourself, then obviously it depends on what you do with these pointers in the function... – user17732522 Oct 03 '22 at 17:34
  • It is *legal* to call that function with `mybuf` as you wrote it. Whether or not it breaks things is up to the implementation of `SPI_TransmitReceive` – Cory Kramer Oct 03 '22 at 17:34
  • 1
    This is no different than having `int x = 0;` then `int& y = x;` and `const int& z = x;` you can have multiple references to the same object, that differ by `const` – Cory Kramer Oct 03 '22 at 17:36
  • 2
    Might be of interest [What does the restrict keyword mean in C++?](https://stackoverflow.com/questions/776283/what-does-the-restrict-keyword-mean-in-c) – Richard Critten Oct 03 '22 at 17:36
  • No. There is no Undefined Behavior in the code shown here. The compiler is aware that your two pointers may point to the same data. – Drew Dormann Oct 03 '22 at 17:41
  • 1
    `memmove` is specifically designed for the overlapping cases, where `memcpy` fails. It's literally the only difference between `memmove` and `memcpy`. Now, completely overlapping is unusual (normally there's a partial overlap, to shift data up or down in a buffer), but can happen when the immediate caller doesn't know the pointers are equal. If worried, you might protect the memmove call with `if (txbuf != rxbuf)` – Ben Voigt Oct 03 '22 at 17:57

1 Answers1

0

Well, they'll point to the same place. If the code in SPI_TransmitReceive does rxbuf[2] = 3, then following that call, it'll see that txbuf[2] == 3. Some functions may not be expecting that situation; you'd need to check the documentation (or the source code) to see whether it screws things up. But from a language perspective the behavior is still well-defined.

Sneftel
  • 40,271
  • 12
  • 71
  • 104