Bufory pamięci współdzielonej w C ++ bez naruszania surowych reguł aliasingu

Walczę z implementacją wspólnego bufora pamięci bez łamania surowych reguł aliasingu C99.

Przypuśćmy, że mam jakiś kod, który przetwarza niektóre dane i musi mieć trochę pamięci „scratch” do działania. Mógłbym napisać to jako coś w stylu:

void foo(... some arguments here ...) {
  int* scratchMem = new int[1000];   // Allocate.
  // Do stuff...
  delete[] scratchMem;  // Free.
}

Następnie mam inną funkcję, która wykonuje inne rzeczy, które również wymagają bufora scratch:

void bar(...arguments...) {
  float* scratchMem = new float[1000];   // Allocate.
  // Do other stuff...
  delete[] scratchMem;  // Free.
}

Problem polega na tym, że foo () i bar () mogą być wywoływane wiele razy podczas pracy i alokacja sterty w całym miejscu może być dość zła pod względem wydajności i fragmentacji pamięci. Oczywistym rozwiązaniem byłoby jednorazowe przydzielenie wspólnego, współdzielonego bufora pamięci o odpowiednim rozmiarze, a następnie przekazanie go do foo () i bar () jako argumentu, w stylu BYOB:

void foo(void* scratchMem);
void bar(void* scratchMem);

int main() {
  const int iAmBigEnough = 5000;
  int* scratchMem = new int[iAmBigEnough];

  foo(scratchMem);
  bar(scratchMem);

  delete[] scratchMem;
  return 0;
}

void foo(void* scratchMem) {
  int* smem = (int*)scratchMem;
  // Dereferencing smem will break strict-aliasing rules!
  // ...
}

void bar(void* scratchMem) {
  float* smem = (float*)scratchMem;
  // Dereferencing smem will break strict-aliasing rules!
  // ...
}


Myślę, że mam teraz dwa pytania:
- W jaki sposób mogę zaimplementować wspólny wspólny bufor pamięci, który nie narusza reguł aliasingu?
- Mimo że powyższy kod narusza surowe reguły aliasingu, nie ma „krzywdy” przy aliasie. W związku z tym czy jakikolwiek sensowny kompilator może wygenerować (zoptymalizowany) kod, który nadal wpędza mnie w kłopoty?

Dzięki

questionAnswers(3)

yourAnswerToTheQuestion