Итак, есть много сообщений о том, что вы не должны делать printf("%s is your password");
, и что вам просто повезло.По твоему вопросу, я полагаю, ты это знал.Но мало кто говорит вам вероятную причину , почему вам повезло.
Чтобы понять, что, вероятно, произошло, мы должны понять, как передаются параметры функции.Вызывающая функция должна поместить параметры в согласованное место, чтобы функция могла найти параметры.Поэтому для параметров 1 ... N мы называем эти места r1
... rN
.(Такое соглашение является частью того, что мы называем «соглашением о вызове функций»)
Это означает, что этот код:
scanf("%s", password);
printf("%s is your password",password);
может быть преобразован компилятором в этот псевдокод
r1="%s";
r2=password;
call scanf;
r1="%s is your password";
r2=password;
call printf;
Если вы теперь удалите второй параметр из вызова printf
, ваш псевдокод будет выглядеть следующим образом:
r1="%s";
r2=password;
call scanf;
r1="%s is your password";
call printf;
Помните, что после call scanf;
, r2
может быть неизменным и все равно иметь значение password
, поэтому call printf;
"работает"
Вы можете подумать, что обнаружили новый способ оптимизации кода, исключив одно из r2=password;
назначений,Это может быть верно для старых «тупых» компиляторов, но не для современных.
Современные компиляторы уже будут делать это, когда это безопасно.И это не всегда безопасно.Причины, по которым это небезопасно, могут заключаться в том, что scanf
и printf
имеют разные соглашения о вызовах, r2
могли быть изменены за вашей спиной и т. Д.
Чтобы лучше понять, чтокомпилятор делает, я рекомендую посмотреть выходные данные ассемблера вашего компилятора, на разных уровнях оптимизации.
И, пожалуйста, всегда компилируйте с -Wall
.Компилятор часто хорошо говорит вам, когда вы делаете глупости.