Sie sind ein Opfer von unsigned ganzen Zahlen :)
std::string::size()
gibt eine unsigned integer (vom Typ entspricht size_t
).
Wenn der Compiler wertet input.size() - 1
, diese Art von wird size_t(0) - 1
, und da die Berechnung mit unsigned ganzen Zahlen durchgeführt wird, statt -1 Sie eine sehr große ganze Zahl (MSVC 32-Bit-Compiler drucken 4294967295
, erhalten, die entspricht bis zum maximal 32-Bit unsigned Integer-Wert 2^32 - 1
).
Also diese Schleife:
for (int i = 0; i < input.size() - 1; ++i)
ist eine Art entspricht:
for (int i = 0; i < /* very big positive number */; ++i)
, die Ihre Nachricht viele mal gedruckt werden.
Stattdessen im zweiten Fall, wenn man input.size() - 1
auszuwerten und ordnen sie dann zu einem int
Variable (die signed
Standardeinstellung), der Compiler berechnet noch size_t(0) - 1
als eine sehr große positive ganze Zahl ist, aber dann ist diese Zahl umgewandelt zu einem (signed
) int
, mit -1
in checksize
dazu führt, dass initialisiert und die Schleife wird nie ausgeführt:
for (int i = 0; i < checksize /* -1 */; ++i)
in Anbetracht diesen übersetzbar Code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string input;
#ifdef CASE1
for (int i = 0; i < input.size() - 1; ++i)
{
cout << "Entered the loop\n";
}
#else
cout << "input.size() - 1 == " << (input.size() - 1) << '\n';
cout << "SIZE_MAX == " << SIZE_MAX << '\n';
int checkSize = input.size() - 1;
cout << "checkSize == " << checkSize << '\n';
for (int i = 0; i < checkSize; ++i)
{
cout << "Entered the loop\n";
}
#endif
}
Wenn Sie seine CASE1
mit MSVC und /W4
(Warnstufe 4, die ich sehr vorschlagen) kompilieren, erhalten Sie eine Warnung für Ihre for
Schleifenbedingung:
cl /EHsc /W4 /nologo /DCASE1 test.cpp
test.cpp(10) : warning C4018: '<' : signed/unsigned mismatch
, die normalerweise auf Sie zeigt, dass etwas mit Ihrem Code nicht stimmt. Statt
, ohne CASE1
Kompilieren gibt keine Warnungen und die folgende Ausgabe (was zeigt, dass die körpereigene for
Schleife nie ausgeführt):
cl /EHsc /W4 /nologo test.cpp
input.size() - 1 == 4294967295
SIZE_MAX == 4294967295
checkSize == -1
keine Compiler-Warnungen? – LogicStuff
Die meisten Compiler haben standardmäßig eine signierte-unsignierte Warnung, die viele Fehlalarme generiert. Einige Compiler warnen vor einer Zuweisung außerhalb des Bereichs im 2. Beispiel –
. Deshalb sollten Zahlen, die für Mathe verwendet werden, unterzeichnet werden. – Barry