Здесь нужно обсудить два момента:
Место для нулевого терминатора
Теоретически реализация C ++ 03 могла бы избежать выделения места длятерминатор и / или, возможно, потребовалось выполнить копии (например, unsharing ).
Тем не менее, все вменяемые реализации выделяли место для нулевого терминатора для поддержки c_str()
для начала,потому что в противном случае это было бы практически непригодно, если бы это не было тривиальным вызовом.
Сам нуль-терминатор
Это правда, что некоторые очень (1999), очень старые реализации (2001) записывали \0
каждый c_str()
вызов.
Однако основные реализации изменились (2004) или были уже такими (2010), чтобы избежать подобных вещей до выхода C ++ 11, поэтому, когда появился новый стандарт, для многих пользователей ничего не изменилось.
Теперь, должна ли была быть реализована реализация C ++ 03это или нет:
Мне кажется, чтотрата процессорных циклов
Не совсем.Если вы звоните c_str()
более одного раза, вы уже напрасно тратите время, записывая его несколько раз.Мало того, вы возитесь с иерархией кеша, что важно учитывать в многопоточных системах.Напомним, что многоядерные / SMT-процессоры начали появляться между 2001 и 2006 , что объясняет переход к современным реализациям, не относящимся к CoW (даже если было несколько многопроцессорных систем на паруза десятилетия до этого).
Единственная ситуация, когда вы могли бы спасти что-либо, это если бы вы никогда не назвали c_str()
.Однако обратите внимание, что когда вы изменяете размер строки, вы все равно переписываете все.Дополнительный байт будет трудно измеримым.
Другими словами, не при записи терминатора при изменении размера вы подвергаете себя худшей производительности / задержке.Если вы записываете один раз , в то же время вам приходится выполнять копирование строки, поведение производительности становится более предсказуемым, и вы избегаете ловушек производительности, если в конечном итоге вы используете c_str()
, особенно в многопоточных системах.