2010-05-01 6 views
11

Есть ли способ определить, используя тип typedef integer/float, который не подразумевает отсутствие псевдонимов?C/C++ __restrict type

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

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

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

+0

Я думаю, он компилируется, если я делаю 'typedef const double * __restrict type;' но создает ли это ограничение double * или какой-то ограничитель, применяемый к 'type'? – Anycorn

+0

Попробуйте и посмотрите. 'ограничение' не определяется стандартом C++, поэтому ymmv. Если я правильно помню свой собственный опыт, ограничьте участие в typedefs в GCC. – Potatoswatter

+0

@P как я могу это сделать? посмотреть на сборку напрямую и увидеть разницу? ограничить в c99, я думал, что __restrict был C++? – Anycorn

ответ

19

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

В C++ 1998 стандарт устанавливает, что «typedef спецификатор не должны ... быть объединены в Децл-спецификатор-сл с любым видом спецификатора кроме типа спецификаторов.» По существу, это должен быть список спецификаторов типа, который включает в себя два cv-квалификаторы, 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, он действительно не выполнял правильную оптимизацию до version 4.5.

+0

«C99 определяет typedef аналогично, за исключением того, что его список квалификаторов включает ограничение». Я сделал [вопрос об этом] (http://stackoverflow.com/q/43631062/2542702), и все (что прокомментировало до сих пор) считают, что это плохая идея. Вы можете прокомментировать? Является ли это законным C для typedef указателя с ограничением? –