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
  • 57,834
  • 11
  • 73
  • 112
Vorac
  • 8,726
  • 11
  • 58
  • 101
  • `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
  • 829
  • 3
  • 9
  • 19