Lorsque je travaillais sur string::npos
, j’ai remarqué quelque chose et je n’ai trouvé aucune explication à ce sujet sur le Web.
(string::npos == ULONG_MAX)
et
(string::npos == -1)
sont vrai.
Alors j'ai essayé ceci:
(18446744073709551615 == -1)
ce qui est également vrai.
Comment cela peut-il être possible? Est-ce à cause d'une conversation binaire?
string::npos
est défini comme constexpr static std::string::size_type string::npos = -1;
(ou s'il est défini dans la définition de la classe, il s'agirait de constexpr static size_type npos = -1;
mais ce n'est vraiment pas pertinent).
L'enveloppe des nombres négatifs convertis en types non signés (std::string::size_type
est fondamentalement std::size_t
, qui est non signé) est parfaitement définie par la norme. -1
encapsule la plus grande valeur représentable du type non signé, qui dans votre cas est 18446744073709551615
. Notez que la valeur exacte est définie par l'implémentation car la taille de std::size_t
est définie par l'implémentation (mais capable de contenir la taille du plus grand tableau possible sur le système en question).
Selon la norme C++ (numéro de document: N3337 ou numéro de document: N4296), std::string::npos
est défini comme suit:
static const size_type npos = -1;
où std :: string :: size_type est un type entier non signé. Il n’ya donc rien de merveilleux que std :: string :: npos soit égal à -1. L'initialiseur est converti au tyhpe de std::string::npos
.
Quant à cette équation
(string::npos == ULONG_MAX) is true,
alors cela signifie que le type std::string::npos
a tapé dans l'implémentation utilisée unsigned long
. Ce type correspond généralement au type size_t
.
Dans cette équation
(18446744073709551615 == -1)
Le littéral gauche a un type intégral non signé qui convient pour stocker un littéral si gros. Ainsi, l'opérande droit est également converti en ce type non signé en propageant le bit de signe. Comme l'opérande de gauche représente lui-même la valeur maximale du type, ils sont égaux.
Tout est question de débordement signé et du fait que les nombres négatifs sont stockés en tant que complément à 2. Cela signifie que pour obtenir la valeur absolue d'un nombre négatif, vous devez inverser tous les bits et en ajouter un. Signification lorsque vous effectuez une comparaison sur 8 bits 255 et -1 ont la même valeur binaire que 11111111. Il en va de même pour les entiers plus grands