Я искал исходный код для nmap, который был выпущен в 1997 году, и заметил этот фрагмент кода, который выглядит немного странным для меня:
int i=0, j=0,start,end;
char *expr = strdup(origexpr);
ports = safe_malloc(65536 * sizeof(short));
i++; /* <<<<<< */
i--; /* <<<<<< */
for(;j < exlen; j++)
if (expr[j] != ' ') expr[i++] = expr[j];
expr[i] = '\0';
Зачем тебе i++;
и то i--;
сразу после друг друга? i
есть 0
, то i++
превращается i
в 1
. После этого i--
превращается i
в 0
.
Ссылка на оригинальный исходный код. Ищи:
i++;
i--;
Кто-нибудь может объяснить, для чего это?
-O
этим действительно оптимизируются эти операторы.Ответы:
Это была ошибка. Эти строки вместе
i
остаются неизменными, поэтому их не должно было быть.Связанная статья, которая представила nmap, была опубликована 1 сентября 1997 года. Если вы посмотрите SVN-репозиторий для nmap по адресу https://svn.nmap.org/nmap , то первоначальная версия, проверенная 10 февраля 1998 года, не имеет таких строк:
Так что это то, что автор нашел и исправил между публикацией исходного исходного кода nmap и начальной регистрацией в SVN.
источник
<pre>
тоже нет тегов вокруг статьи; Инспектор Chrome показывает, как это приводит к искажению документов во время создания DOM;)i
не int, а какой-то причудливый класс с перегрузками операторов, возможно (хотя это маловероятно и, как правило, признак плохой практики кодирования), что это может иметь некоторые побочные эффекты. (Применимо, только если это был C ++, конечно.)Это бесполезно. Это абсолютно ничего не делает.
Если бы я предположил, что это, вероятно, остатки некоторого кода отладки, который использовался во время разработки.
Я предполагаю, что либо один из
i++
илиi--
было введено в одном изменении, а другое - в другом.Однако у меня нет возможности найти точку введения, поскольку между первоначальным исходным выпуском и первой ревизией SVN не было истории изменений.
источник
Для неоптимизирующего компилятора или компилятора, распознающего побочные эффекты оборудования, i ++; i-- последовательность приведет к тому, что i будет считываться из памяти, а затем перезаписываться независимо от пути, пройденного через цикл for и вложенного в if.
При параллельной обработке иногда используются взломы компилятора, чтобы гарантировать, что последовательность кода использует свои собственные локальные копии переменных, а не глобальные копии.
Поскольку пример представляет собой фрагмент кода, нельзя определить используемый компилятор, ожидаемую операционную систему / аппаратное обеспечение, а также то, находится ли это в последовательности / функции кода, которую можно выполнить как независимый поток.
В более простых системах я временно вынудил изменения переменных использовать функцию прерывания в среде отладки. Если бы это было так, автор, возможно, забыл удалить код, когда разработка была завершена.
источник
i
в качестве локальной переменной показано в приведенном выше коде, и нет другого способа получить доступ к нему из другого потока в той точке, гдеi++; i--
находятся строки.i
быть вынужденным быть энергонезависимым. Я не имел дело с многопоточностью в C или C ++, поэтому я понятия не имею, как это можно трактовать как изменчивое и какi++; i--
это подавить.Я предлагаю вам проверить только обновленный код. Если вы используете (i = 2 + 1) сразу после этого (i-1), это не имеет смысла. Значение i остается неизменным. Вы можете попробовать это, используя любой компилятор c или c ++. или даже на любом другом языке это то же самое. Запустите код в компиляторе, чтобы увидеть, ошибаюсь я или нет, и дайте мне знать, если я даю неправильный ответ.
источник