Я пишу в C для OSX, работая на 64-битной машине в 32-битном режиме. Я собираюсь использовать GCC для 386. Проект большой; Я не видел какого-либо странного поведения от компилятора (возможно, до сих пор.) Приложение многопоточно, и этот код должен быть, но в настоящее время выполняется однопоточным. Я компилирую с помощью независимого положения clib и используя posix-потоки при поточной передаче. Этот код, кстати, действует точно так же, если я do его нить.Мои неподписанные короткие указатели возвращают неожиданные результаты. Зачем?
Следующая упрощенная процедура, демонстрирующая проблему в простейшей форме. В принципе, я перемещаю 16-битные каналы изображения здесь из одного набора из трех каналов RGB (mr, mg, mb) в другой набор из 3 каналов RGB (lr, lg, lb) точно такого же размера. Фрагмент, как я собираюсь сбросить его, работает отлично:
void lrip_me( unsigned short *mr, // RIP from source image
unsigned short *mg,
unsigned short *mb,
unsigned short *lr, // into RGB layer
unsigned short *lg,
unsigned short *lb,
struct layer *lay,
long start,long finish)
{
long xw,yw;
long xf,yf;
long x,y;
unsigned long offset;
xw = lay->parent->x;
yw = lay->parent->y;
xf = xw - 1;
yf = yw - 1;
for (y=start; y<finish; y++)
{
for (x=0; x<xw; x++)
{
offset = (y * xw) + x;
if (x==0 || x==xf || y==0 || y==yf) // then on edge
{
lr[offset] = mr[offset];
lg[offset] = mg[offset];
lb[offset] = mb[offset];
}
else
{
lr[offset] = mr[offset];
lg[offset] = mg[offset];
lb[offset] = mb[offset];
}
}
}
}
Как вы можете видеть, действие на краю изображения, так и внутри краев одно и то же; Я просто перемещаю данные. И это работает - вывод этого изображения в каналах lr, lg и lb.
НО. Если в предложении еще, я изменить строки читать ...
lr[offset] = mr[offset-xw];
lg[offset] = mg[offset-xw];
lb[offset] = mb[offset-xw];
... Вы ожидали бы интерьер изображения, чтобы переместить одну строку развертки, так как извлекает данные будут Выходец из полное расстояние от линии сканирования, но переход в неперемещенное целевое местоположение. Вместо этого вывод выглядит совершенно случайным. Словно шорты были загружены на неправильные границы, возможно, или из другого места. Это делает то же самое ...
lr[offset] = mr[offset-1];
lg[offset] = mg[offset-1];
lb[offset] = mb[offset-1];
... там, я ожидаю, что изображение будет перемещаться по одному пикселю по горизонтали. Нет. Тот же результат - чистый хеш.
Я попытался перейти на математику указателя вместо массивов // * (mr + offset-1) // и получить точно такой же результат. Я скомпилировал его в библиотеке и в среде objc. Я попытался использовать даже смещение, думая, возможно, компилятор смущен размером данных. Я получаю одинаковые результаты каждый раз. Значение смещения может использоваться как есть, но ТОЛЬКО как есть. Он не может быть изменен в скобках, и, кроме того, он не может быть изменен вне кронштейнов, просто считаться длинным.
У меня нет идеи, что здесь происходит. Я был бы очень благодарен, если бы кто-нибудь помог мне понять, что есть.
Немного фона; это операция RIP (удаление изолированного пикселя), или, по крайней мере, это будет, если я смогу получить в 8 пикселах, окружающих тот, который в данный момент просматривает цикл. Вот почему кромки обрабатываются по-разному; Я не хочу, чтобы запустить 8-пиксельный lookaround по краям, только внутри них, где я всегда буду иметь все 8 посмотреть на:
ooo
oxo
ooo
В этом тесте, я удалил все RIP кода, поскольку он добавляет много сложности и не проливает свет на проблему. Просто (ха-ха!) Ситутация, где смещения массива и указателя, похоже, не работают разумно.
Макет массивов в памяти полностью определен языком C. Для вариантов исполнения нет места. –
Нет, я тот, кто поставил их в строгом порядке. И, как я уже сказал, пример работает так, как это было дано - выход прекрасен при вычислении; это не так, если расчет смещения был неправильным. Согласовано? – fyngyrz
@fyngyrz, не согласовано. В простом случае копирования (или где-нибудь, где вы работаете только на одном пикселе (элемент массива)), не имеет значения, какой порядок вы выполняете по ним, пока вы все равно генерируете каждое смещение. Однако, думая об этом больше, я думаю, что если бы была проблема с строкой-строкой против большого столбца, тогда ваша вторая модификация ('foo [offset-1]') должна была работать. – rlibby