Расширение gcc C ++ для ненулевого выделения указателя массива?
Я ищу расширение языка C ++, поддерживаемое gcc, чтобы можно было использовать указатели массива, не основанные на нулях. В идеале я мог бы просто написать:
#include<iostream>
using namespace std;
// Allocate elements array[lo..hi-1], and return the new array.
template<typename Elem>
Elem* Create_Array(int lo, int hi)
{
return new Elem[hi-lo] - lo;
// FIXME what about [expr.add]/4.
// How do we create a pointer outside the array bounds?
}
// Deallocate an array previously allocated via Create_Array.
template<typename Elem>
void Destroy_Array(Elem* array, int lo, int hi)
{
delete[](array + lo);
}
int main()
{
const int LO = 1000000000;
const int HI = LO + 10;
int* array = Create_Array<int>(LO, HI);
for (int i=LO; i<HI; i++)
array[i] = i;
for (int i=LO; i<HI; i++)
cout << array[i] << "\n";
Destroy_Array(array, LO, HI);
}
Вышеприведенный код работает, но не определен стандартом C ++. В частности, проблема заключается в [Expr.add] / 4:
Когда выражение с целочисленным типом добавляется или вычитается из указателя, результат имеет тип операнда указателя. Если выражение P указывает на элемент x [i] объекта массива x с n элементами, выражения P + J и J + P (где J имеет значение j) указывают на (возможно, гипотетический) элемент x [i + j] если 0 ≤ i + j ≤ n; иначе поведение не определено. Аналогично, выражение P - J указывает на (возможно, гипотетический) элемент x [i - j], если 0 ≤ i - j ≤ n; в противном случае поведение не определено.
Другими словами, поведение не определено для строки, помеченной как FIXME в приведенном выше коде, потому что он вычисляет указатель, который находится за пределами диапазонаx[0..n]
для массива на основе 0x
.
Есть ли там--std=...
вариантgcc
чтобы сказать, что можно напрямую рассчитывать ненулевые указатели на массивы?
Если нет, то есть ли достаточно удобный способ эмулироватьreturn new Type[hi-lo] - lo;
утверждение, возможно, приведя кlong
и назад? (но тогда я бы беспокоился о появлении новых ошибок)
Кроме того, можно ли это сделать так, чтобы для отслеживания каждого массива требовался только 1 регистр, как в коде выше? Например, если у меня естьarray1[i], array2[i], array3[i]
для этого требуется только 3 регистра для указателей массиваarray1, array2, array3
, плюс один регистр дляi
? (Точно так же, при холодной выборке ссылок на массивы, мы должны иметь возможность просто получить указатель, не основанный на нуле, напрямую, не выполняя вычисления просто для установления ссылки в регистрах