Ваша программа имеет неопределенное поведение.
Сдвиг hash << 5
переполнится, что имеет неопределенное поведение для целочисленных типов со знаком до C ++ 20.
В частности, это означает, что вызов вашей функции никогда не может привести к константному выражению, которое вы можете проверить, добавив constexpr
к вашему объявлению i
. Затем оба компилятора должны будут диагностировать неопределенное поведение и сообщат вам об этом.
Дайте hash
тип без знака, и ваш код будет на самом деле иметь четко определенное поведение, а выражение djb2("hello you :)"
будет фактически константное выражение, которое может быть вычислено во время компиляции, при условии, что вы используете C ++ 14 или более позднюю версию (l oop не было разрешено в функции constexpr
в C ++ 11.).
Для этого по-прежнему не требуется, чтобы компилятор действительно выполнял оценку во время компиляции, но затем вы можете форсировать его, добавив constexpr
к объявлению i
.
" Force"здесь относительно. Из-за правила как-будто и из-за отсутствия наблюдаемой разницы между вычислением во время компиляции и во время выполнения, компилятору по-прежнему не требуется технически выполнять вычисления только во время компиляции. -time, но он требует, чтобы компилятор проверил весь расчет на достоверность, что в основном совпадает с его оценкой, поэтому для компилятора было бы неразумным повторять оценку во время выполнения.
Аналогично " может оцениваться во время компиляции"также относительно. Опять же по тем же причинам, что и выше, компилятор может по-прежнему выбирать вычисления во время компиляции, даже если они не являются константным выражением, если не будет заметных различий в поведении. Это чисто вопрос качества оптимизатора. В вашем конкретном случае c программа имеет неопределенное поведение, поэтому компиляторы могут в любом случае делать то, что они хотят.