Почему я ++; я--; сразу после друг друга? - PullRequest
164 голосов
/ 28 марта 2020

Я искал исходный код для 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--;

Может кто-нибудь объяснить, что это для?

Ответы [ 4 ]

152 голосов
/ 28 марта 2020

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

Связанная статья, которая представила nmap, была опубликована 1 сентября 1997 года. Если вы посмотрите на репозиторий SVN для nmap в https://svn.nmap.org/nmap, в первоначальной редакции, зарегистрированной 10 февраля 1998 года, нет этих строк:

int i=0, j=0,start,end;
char *expr = strdup(origexpr);
char *mem = expr;

ports = safe_malloc(65536 * sizeof(short));
for(;j < exlen; j++) 
  if (expr[j] != ' ') expr[i++] = expr[j]; 
expr[i] = '\0';

Так что это то, что автор нашел и исправил между публикацией исходного кода nmap и начальная регистрация в SVN.

40 голосов
/ 28 марта 2020

Это бесполезно. Это абсолютно ничего не делает.

Если бы я предположил, это, вероятно, остатки некоторого кода отладки, который использовался во время разработки.

Я предполагаю, что либо один из i++ или i-- было введено в одно изменение, а другое было введено в другое.

Однако у меня нет способа найти точку введения, поскольку между первоначальным исходным выпуском и первой ревизией SVN не было истории изменений.

9 голосов
/ 31 марта 2020

Для неоптимизирующего компилятора или компилятора, распознающего побочные эффекты оборудования, i ++; i-- последовательность приведет к тому, что i будет считываться из памяти, а затем перезаписываться независимо от пути, пройденного через for l oop и вложенного, если.

При параллельной обработке иногда хаки компилятора принимаются убедитесь, что последовательность кода использует свои собственные локальные копии переменных, а не глобальные копии.

Так как пример является фрагментом кода, невозможно определить используемый компилятор, ожидаемую операционную систему / аппаратное обеспечение, а также то, находится ли это в последовательности / функции кода, которую можно выполнить как независимый поток.

В более простых системах я временно заставил изменения в переменных использовать функцию прерывания в среде отладки. Если бы это было так, автор, возможно, забыл удалить код после завершения разработки.

2 голосов
/ 08 апреля 2020

Я предлагаю вам проверить только обновленный код. Если вы используете (i = 2 + 1) сразу после этого (i-1), это не имеет смысла. Значение i остается неизменным. Вы можете попробовать это, используя любой компилятор c или c ++. или даже на любом другом языке это то же самое. Запустите код в компиляторе, чтобы увидеть, ошибаюсь я или нет, и дайте мне знать, если я даю неправильный ответ.

...