Будет немного догадываться, почему const имеет значение, но можно сделать разумное предположение.
Переменные с областью действия блока, такие как result
, могут быть размещены в регистре или помещены в стек. Есть много факторов, которые влияют на то, используется ли регистр. Вполне возможно, что const
имеет значение, в этом случае. В конце концов, это право компиляторов использовать то, что, по его мнению, работает лучше всего.
Аналогично, аргументы функций могут передаваться в регистрах или в стеке. Поскольку функции часто компилируются отдельно, их интерфейс (то есть объявление) определяет, какой аргумент идет куда. printf (...) является особым случаем, так как его можно вызывать с аргументами разных типов. В результате, какие данные в конечном итоге будут меняться, и вам нужно указать printf (...), чего ожидать.
Теперь при передаче переменной в функцию компилятор обычно должен ее скопировать. От регистра к стеку, от одного регистра к другому и т. Д., Существует довольно много возможных вариантов. Как я указывал, местоположение источника может отличаться в зависимости от наличия или отсутствия const
.
Теперь, когда это происходит, вы передаете неправильный спецификатор формата printf(...)
, а именно %u
вместо %ld
. Это может привести к тому, что printf (...) будет искать неправильное место для получения своих данных - возможно, в регистре, а не в стеке, или наоборот. Такое действие может привести к довольно неожиданным результатам. printf(...)
может, например, наткнуться на ваш не скопированный result
или случайные старые значения в каком-то регистре. Кажется, что в неконстантном случае он находит правильное значение (даже если бы он нашел его в неправильном месте), тогда как в константном случае printf(...)
просто находит мусор.