2009-06-07 5 views
2

Учитывая этот код, VC9 не обнаруживает сглаживание:ограничивают-edness с предварительно c99

typedef struct { int x, y; } vec_t; 

void rotate_cw(vec_t const *from, 
       vec_t  *to) 
{ 
     /* Notice x depends on y and vice versa */ 
     to->x = from->y; 
     to->y = -from->x; 
} 

/* ... */ 
vec_t a, b; 
rotate_cw(&a, &b); /* OK, no aliasing */ 
rotate_cw(&a, &a); /* FAIL, aliasing is not detected */ 

Очевидное исправление использовать временное:

void rotate_cw(vec_t const *from, 
       vec_t  *to) 
{ 
     int temp = from->x; 
     to->x = from->y; 
     to->y = -temp; 
} 

Это стандартное поведение? Я ожидал, что компилятор, если не сказать так, предположил бы, что оба указателя будут, возможно, псевдонимом.

+4

Да, это не стандартное поведение - выглядит как ошибка компилятора, по крайней мере, на C99 и C++. Им явно разрешено псевдонимы друг другу. Я не знаю, как это было на C89, и для вас это похоже :(Но я думаю, что читал на C89, все было еще более допустимо –

+0

Вы ожидаете, что c позаботится о том, чтобы у вас был угловой футляр «Это не так: вы ожидаете, что будете беспокоиться об этих деталях для себя. Это может послужить основанием для рассмотрения языка более высокого уровня, но это * не * ошибка в c: компилятор делает именно то, что вы скажете это. – dmckee

+0

@ dmckee: Чтобы быть справедливым, исправленная версия появилась на первом месте, и мне очень нравится мой макроассемблер;) – diapir

ответ

4

Check out this answer.

Попробуйте поставить __restrict перед параметрами, кажется, единственный способ получить MSVC, чтобы дать какие-либо предупреждения.

+0

Спасибо за ссылку. Мне бы скорее понадобилось ключевое слово __norestrict, поэтому компилятор не допускает ограничений. – diapir

4

Код в хорошем состоянии, на C89 или C99. Это неясно, но компилятор ничего не диагностирует, поэтому он не диагностирует.

Если вы использовали C99 и «ограничивали» оба параметра функции, тогда вы получили бы ошибку - если ваш компилятор поддерживает C99. AFAIK, текущая версия MSVC не поддерживает полностью C99.

0

Прежде чем C99 изобрел классификатор restrict, некоторые компиляторы C включили опции оптимизации, которые будут направлять их на определенные предположения об использовании указателя; руководства, которые я видел для таких компиляторов, прямо предупреждали, что такие оптимизации были не совместимыми со стандартами и могут произвольно вызывать код с использованием определенных конкретных конструкций, поведение которых было определено стандартом, чтобы вести себя так, как это противоречило стандарту и намерение программиста. С точки зрения руководства, оптимизация рассказала компилятору о компиляции подмножества C, которое не определяло поведение определенных угловых случаев, которые были определены на C, но которые позволили бы генерировать более эффективный код для этих случаев сделал определение.