C / C ++ __restrict тип - PullRequest
       48

C / C ++ __restrict тип

11 голосов
/ 01 мая 2010

Есть ли способ определения с использованием typedef типа Integration / Float, который не подразумевает псевдоним?

что-то эквивалентное (но примитивная конструкция):

template < typename T >
struct restrict { T* __restrict data; };

как связанный вопрос, можно ли спросить gcc, что он определяет псевдоним / нет псевдоним указателя?

1 Ответ

20 голосов
/ 01 мая 2010

Как отмечается в комментариях, многие новые компиляторы C ++ поддерживают реализацию C99 ограничителя типа restrict. Поскольку restrict не является зарезервированным ключевым словом в C ++, компиляторы обычно используют __restrict или __restrict__. И GCC , и Visual C ++ прекрасно описывают это с явными ссылками на C99.

Стандарт C ++ 1998 гласит, что "спецификатор typedef не должен ... объединяться в decl-specier-seq с любым типом спецификатора, кроме спецификатора типа «. По сути, это должен быть список спецификаторов типов , который включает два cv-qualifiers , const и volatile.

C99 определяет typedef аналогично, за исключением того, что его список квалификаторов включает restrict.

Казалось бы, разумно ожидать аналогичной поддержки в typedefs для нестандартных __restrict ... но вы никогда не знаете!

Умный и простой способ проверить это следующим образом:

extern void link_fail();

typedef int *__restrict restricted_int_p;

void test(restricted_int_p a, restricted_int_p b) {
    *a = 1;
    *b = 2;

    if (*a == 2) link_fail();
}

Это просто использует тот факт, что, если в объектном файле будет найден неразрешенный символ link_fail, компоновщик выдаст ошибку. Если компилятор правильно ограничивает два аргумента, он должен знать значение a, даже после изменения b. Таким образом, он должен удалить весь блок if из сгенерированного объектного файла, поскольку он никогда не будет запущен.

Обратите внимание, что хотя GCC поддерживал синтаксис ограничения начиная с версии 3.0, он действительно не выполнял надлежащую оптимизацию до версии 4.5 .

...