0

I have this code sample in which I try to concatenate strings:

const char* NameErrorException::what() const throw()
{
    return "NameError : name '" + _name + "' is not defined";
}

Why cant I create a char* by use of + between strings?

13
  • stackoverflow.com/questions/662918/… Commented Dec 14, 2016 at 12:34
  • 1
    You can't use + to concatenate them. Either use strcat or the more safe way snprintf. Actually, just use std::string. Commented Dec 14, 2016 at 12:34
  • 3
    because C++ is not Java (this is by far, the best answer here) Commented Dec 14, 2016 at 12:34
  • 3
    @GillBates Yes. Institutions should start teaching modern C++, that I agree with. Commented Dec 14, 2016 at 12:45
  • 2
    Or they could teach C and assembler before teaching C++, so that programmers actually have a clue about what they are doing. Now if there existed a language with was sane, compiled and fast at the same time, we wouldn't need C or C++ at all... For now, we'll just have to settle for compiled and fast. Commented Dec 14, 2016 at 12:49

4 Answers 4

6

"Sesame Street 3" plus 4 houses ahead means "Sesame Street 7".

but what does "Sesame Street 3" plus "Sesame Street 4" means?
it means nothing.
you can add a house-offset to a street address, but what does it even mean to add two street addresses together? it makes no sense. "Sesame Street 3" plus "Sesame Street 4" IS NOT "Sesame Street 7".

const char* is a location of a character on the RAM. adding yet another location will not create new string. it is meaningless. just like adding two street addresses will not create a new street address (or a new street, for that example).

const char* is (usually) C-String. it knows nothing about string concatenation, splitting, removing or replacing. it's just the location of the first character on the RAM. this is why usually, in C++ we do use std::string. std::string is an object with behaviour. it DOES know about actions like concatenation, splitting, removing or replacing.

Sign up to request clarification or add additional context in comments.

Comments

2

The first part of this is simple: You can't add char * variables with + because C++ is not Java (or Python, or C#).

You may have learnt that "const char* represents a string in C++". This is true as far as it goes, but if you use const char* like that, you have all the responsibility of allocating and freeing memory at the right time.

In general, you are much better off using std::string to represent a string. It is safe to return a std::string from your function - it is not safe to return a const char* (who is responsible for freeing the memory)?

However, there is one exception to that rule: When you are overriding std::exception::what() - which is defined to return a const char*. The fix is that you need an additional (std::string) member of NameErrorException which you construct at the same time as you construct _name, and which you set to the full error message, and then what just returns _what_error.c_str(). So the full class would look something like:

class NameErrorException : public std::runtime_error
{
    std::string _name;
    std::string _what_error;
    std::string build_error(const std::string &name)
    {
        // Use std::string literals.
        return "NameError : name '"s + name + "' is not defined"s;
    }
public:
    NameErrorException(const std::string& name) 
    : _name(name)
    , _what_error(build_error(name))
    {}

    const char* what() const throw() override
    {
        return _what_error.c_str();
    }
}

If you don't have std::string literals, you will have to make build_error be:

        return std::string("NameError : name '") + name + "' is not defined"s;

1 Comment

I think there is an overload for operator+ with pointers and strings in any order, so one normal string is enough when concatenating multiple strings. It's normally the first operand, but second is good too.
2

A char * is a pointer to a char. The + operator can be used to add an offset to a pointer, not concatenate c strings.

3 Comments

You can add an integer and a pointer, but not two pointers. A nitpick, but terse answers require precise wording.
"For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type." Which is why this won't compile.
@Colin__s - see David Haim's "Sesame Street" answer for a good explanation
-1

You get the error because operator+ is not used for concatenation of c-strings. operator+ is only defined for adding index values to pointers.

You can fix this by creating an std::string object inside the NameErrorException object and initializing it when the exception is created (i.e. in the constructor):

class NameErrorException : public std::runtime_error {
private:
    std::string _errorString;  // Used to store the error message.

public:
    // Constructor.
    NameErrorException(const char * const name) {
        _errorString.append("NameError : name '");
        _errorString.append(name);
        _errorString.append("' is not defined");
    }

    virtual const char * what() {
        return _errorString.c_str();
    }
};

Alternatively, you can create a second const char * buffer that is the correct size, and use std::snprintf() or std::strncat() to create the string. (Remember to clean up the new buffer inside your destructor!)

2 Comments

operator + is defined for all pointer types. otherwise variable + number or variable[index] would not compile.
But it's not defined for addition of two pointer types.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.