Checking comparison of identical C ++ strings

I was shocked by this for several days. I am running a unit test on one of my classes to make sure everything is correct.

However, when comparing the object name, I run into a very strange error. The name is set when the constructor is called. The name is configured correctly based on the notes I am passing. However, in this case, BOOST_CHECK fails

To show how strange this is, here are the values ​​of the two lines in the debugger:

Fdim.name() // "F Diminished"
BOOST_CHECK(Fdim.name() == "F Diminished");  // this fails

      

Here are the specs for two lines taken from the debugger:

Fdim.name() 
// size - 12, capacity - 15, 
// chars: [70, 32, 68, 105, 109, 105, 110, 105, 115, 104, 101, 100]

"F Diminished" stored inside a variable (to see specs of string)
// size - 12, capacity - 15,
// chars: [70, 32, 68, 105, 109, 105, 110, 105, 115, 104, 101, 100]

      

As you can see the lines are identical, but both of them and .compare fail.

Here's even weirder:

std::string n = Fdim.name();
std::string r = "F Diminished";
unsigned val = n.compare(r);       // RETURNS 0, everytime
BOOST_CHECK(val == 0);             // fails 
BOOST_CHECK(val == ((unsigned) 0));// fails

      

I am completely overwhelmed. val always returns 0 when I compare strings (which is why they are equal), but val! = 0 when I compare?

Does anyone know what the problem is? Are there any attributes for the string that I should be aware of that might reset this comparison check?

EDIT *** Strings are stored as std :: string, I am not using char * or cstring. member _name std :: string.

Here is the BOOST OUTPUT:

c:/directory etc(64): error in "ChordIdentification": check val == 0 failed
c:/directory etc(65): error in "ChordIdentification": check n == r failed
c:/directory etc(66): error in "ChordIdentification": check val == ((unsigned) 0) failed
c:/directory etc(67): error in "ChordIdentification": check Fdim.name() == "F Diminished" failed

      

Here's the code for a test case, just to make sure people know what val, n and r are:

BOOST_AUTO_TEST_CASE(ChordIdentification)
{
MAKE_NOTE(Db, 'D', FLAT);   // macro that creates a note
MAKE_NOTE(F, 'F', NATURAL);
MAKE_NOTE(Ab, 'A', FLAT);
MAKE_NOTE(Cb, 'C', FLAT);

Chord DbMajor7 = Chord(Cb, Ab, F, Db);
Chord Fdim = Chord(Ab, Cb, F);

CHORD_TEST(DbMajor7, "Db Dominant7", MAJ, THIRD_INVERSION, DOMINANT7); macro of several boost tests, checking members. This test passes completely for this instance of chord. name() check is passed
std::string n = Fdim.name();
std::string r = "F Diminished";
unsigned val = n.compare(r);
//if (val == 0)
BOOST_CHECK(val == 0);
BOOST_CHECK(n == r);
BOOST_CHECK(Fdim.name() == std::string("F Diminished"));    // these strings fail to compare. no idea why, lengths are same, chars same?????
BOOST_CHECK(std::strcmp(Fdim.name(), "F Diminished") == 0);
CHORD_TEST(Fdim, "F Diminished", DIM, FIRST_INVERSION, DIMINISHED); // partially successful, again the string comparison is responsible for this
}

      

+3


source to share


2 answers


I finally found out why this is happening. This is because the debugger was unable to determine which instance of the child class it was trying to evaluate.

The chord is identified by a polymorphic key map with an abstract base class (Composite_Key), a child (Composite_Key_2Intervals) and a child from this child (Composite_Key_3Intervals)

What was unfortunate was that any test to see if the key was really 3 intervals, or 2, always returned true, because 3 intervals: 2 intervals. The compiler was unable to pick up this and always returned the wrong value found in the lookup table.



Also, the map was never sorted in debugger mode, so the order in which the keys were inserted remains the same. However, they were actually shuffled, resulting in the entire debug evaluation being completely false.

To fix this, I have now made sure that these two classes only inherit from the abstract base, so that they are not related to each other in any way. Now all tests pass and everything returns to the truth.

This cause of this problem was solely the debugger. It hasn't been rated properly.

+3


source


If we look at this:

BOOST_CHECK(Fdim.name() == "F Diminished")

      

then Fdim.name () is a C style string I expect, and as such, only a pointer to a character array - the address of that character array (most likely) is not the same as the address of the string in yours BOOST_CHECK()

.

You can fix this:



BOOST_CHECK(Fdim.name() == string("F Diminished"))

      

or

BOOST_CHECK(strcmp(Fdim.name(), "F Diminished") == 0)

      

+1


source







All Articles