В вашем примере s1.length()
оценивается как 2u
(то есть 2
, но в типе unsigned
), s2.length()
оценивается как 6u
, s1.length() - s2.length()
наиболее вероятно оценивается как 4294967292u
(поскольку в неподписанных типах нет -4
), а s1.length() - s2.length() + 1
оценивается как 4294967293u
.
.length()
и возвращает size_t
в C ++, что является значением без знака.Вычитание значения без знака из другого значения без знака дает значение без знака, например, 1u - 2u
может привести к 4294967295
.
При смешивании значений со знаком и без знака (например, s.length() - 1
или i < s.length()
), значение со знакомпреобразуется в без знака, например, -1 > 1u
обычно составляет true
, поскольку -1
преобразуется в 4294967295
.Современные компиляторы предупредят вас о таком типе сравнений, если вы включите предупреждения.
Зная это, вы можете ожидать, что ваш цикл выполняется для 4 миллиардов итераций, но это не обязательно верно, поскольку i
является подписаннымint
, а если он 32-битный (скорее всего), он не может быть больше 2147483647
.И в тот момент, когда ваша программа увеличивает его с 2147483647
, происходит переполнение со знаком, что является неопределенным поведением в C ++.Так что ваш цикл может очень хорошо работать бесконечно.
Я подозреваю, что вы занимаетесь конкурентным программированием.Моя рекомендация для конкурентного программирования будет всегда приводить .length()
к int
всякий раз, когда вы хотите что-то вычислить.Вы можете создать макрос следующим образом:
#define sz(x) ((int)(x).size())
, а затем написать sz(s)
вместо s.length()
везде, чтобы избежать таких ошибок.
Однако, этот подход сильно недоволен в любой области программирования, где код должен жить дольше, чем несколько часов.Например, в отрасли или с открытым исходным кодом.В таких случаях используйте явные static_cast<int>(s.length())
/ static_cast<ssize_t>(s.length())
каждый раз, когда вам это нужно.Или, что еще лучше, спросите об этом во время проверки кода, чтобы получить конкретные рекомендации относительно вашего кода, существует множество возможных предостережений, см. Комментарии ниже для некоторых примеров.