user1474955
user1474955

Reputation: 23

C++ Very weird behavior while using int in switch

I'm getting some very strange behaviour using the following switch statement:

string recognise_mti(int mti_code)
{
switch(mti_code)
    {
    case 1100:
    case 1101:
        return (mti_code + " (Auth. Request/Repeat)"); break;

    default:
        return (mti_code + " (NOT RECOGNISED)"); break;
    }
}

It seems to return all sorts of things depending on the input integer. It's probably going to turn out to be a silly mistake but as of yet, I'm unable to recognise it. Appreciate any help.

Upvotes: 0

Views: 387

Answers (7)

user1309389
user1309389

Reputation:

You do see that you're adding an integer value to an address of the first byte of a given string literal? This is basically undefined behavior, since you're making an offset of, let's say, 1100 to the "right" (since we're talking about chars, that's the address of something located 1100 bytes down the memory street). For example, in my example, if I try to offset the given string literal's address by 1100, I get "being initialized." That's because the offset address is returned and implicitly converted into a string which gets read as whatever is located at the given address.

Could be anything, my example string, "crazy elephants" or the secret way to enable full C++11 support in MSVC. :P

If I were to try to offset it by one more char (one byte, one offset to the right):

recognise_mti(1100);  // "being initialized."  
recognise_mti(1101); // "eing initialized."

Upvotes: 1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272487

Neither mti_code nor " (Auth. Request/Repeat)" is a std::string. So in fact, all that addition is going to do is pointer addition. So you'll end up with a somewhat random (and probably invalid) pointer, which is then implicitly converted to a std::string.

Try this:

#include <sstream>

...

std::stringstream ss;
ss << mti_code;
switch(mti_code)
    {
    case 1100:
    case 1101:
        ss << " (Auth. Request/Repeat)"; break;

    default:
        ss << " (NOT RECOGNISED)"; break;
    }
return ss.str();

Upvotes: 10

Some programmer dude
Some programmer dude

Reputation: 409166

You are trying to append a string to an integer. That is not possible in C or C++. You have to convert the integer to a string somehow, std::ostringstream is the recommended way:

std::string recognise_mti(const int mti_code)
{
    std::ostringstream ostr;

    switch(mti_code)
    {
    case 1100:
    case 1101:
        ostr << mti_code << " (Auth. Request/Repeat)";
        break;

    default:
        ostr << mti_code << " (NOT RECOGNISED)";
        break;
    }

    return ostr.str();
}

Or if you have a compiler supporting C++11 and std::to_string you can use that:

std::string recognise_mti(const int mti_code)
{
    switch(mti_code)
    {
    case 1100:
    case 1101:
        return std::to_string(mti_code) + " (Auth. Request/Repeat)";

    default:
        return std::to_string(mti_code) + " (NOT RECOGNISED)";
    }
}

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254441

You're trying to add an integer to a C-style string, which doesn't do what you expect. The string is converted to a pointer to its first character, and then that pointer is incremented by 1100 (or whatever) bytes, off the end of the string, and into random memory. If you're lucky, the program will crash; if you're unlucky, then the function will return garbage.

You could use a string stream to build the string:

std::ostringstream result;
switch(mti_code)
{
case 1100:
case 1101:
    result << mti_code << " (Auth. Request/Repeat)"; break;

default:
    result << mti_code << " (NOT RECOGNISED)"; break;
}
return result.str();

or in C++11, you could use std::to_string to convert the integer:

return std::to_string(mti_code) + " (Auth. Request/Repeat)";

Upvotes: 2

Andreas Brinck
Andreas Brinck

Reputation: 52519

You're adding an int to a const char* and returning that as a string.

Upvotes: 0

Matt K
Matt K

Reputation: 13842

You can't concatenate an integer and a string literal with +. You need to convert the integer to a string first. You can do this with a stringstream or with sprintf().

Upvotes: 0

unwind
unwind

Reputation: 399803

You are adding an integer and a string literal. That's not exactly typical in C++ code.

What is likely happening is that you're returning a string constructed from an invalid character pointer, since the literals are (way) shorter than 1100 characters.

Upvotes: 4

Related Questions