1

Here

std::string s{ "aa" }; 
s.length() - 3;  // == very large number

From memory, C's integer promotion rules (idk about C++) produce a type wide enough to fit the result of the calculation and favour unsigned types (for the extra bit of width). But 3 is of type int (right?). So why is the result of type unsigned instead of int or long? unsigned is certainly not wide enough to capture the result of the expression!

cigien
  • 55,661
  • 11
  • 60
  • 99
Vorac
  • 8,164
  • 10
  • 52
  • 97
  • `s.length()` is unsigned so `3` is promoted to unsigned before doing the subtraction. Wrap of unsigned subtraction is well defined. There is a discussion paper on why making the Standard Library container size types unsigned is a problem and that they should all be signed, but that it is too late to change now. – Richard Critten Sep 08 '20 at 13:47
  • 2
    From c++20, there is [std::ssize](https://en.cppreference.com/w/cpp/iterator/size) for exactly this purpose. – cigien Sep 08 '20 at 13:55

1 Answers1

0

string::length has type size_t. For x86-64 platforms modern compilers define size_t as uint64_t. Therefore 3 is promoted to uint64_t. Compiler can not promote it to long or even long long (aka int64_t) because, for example, (1<<64) - 2 can not be represented in signed 64-bit integer. As mentioned in comments, there is string::ssize in C++20 for signed size value.

Michael Lukin
  • 691
  • 3
  • 6
  • 15