tags:

views:

482

answers:

4

why do I get a discard qualifiers error:

customExc.cpp: In member function ‘virtual const char* CustomException::what() const’:
customExc.cpp: error: passing ‘const CustomException’ as ‘this’ argument of ‘char customException::code()’ discards qualifiers

on the following code example

#include <iostream>


class CustomException: public std::exception {

public:

    virtual const char* what() const throw() {
        static std::string msg;
        msg  = "Error: ";
        msg += code();  // <---------- this is the line with the compile error 
        return msg.c_str();
    }

    char code() { return 'F'; }
};

I have searched around on SOF before regarding simular issues.

I have already added a const on every possible place.

Please enlighten me - I don't get the point...

EDIT: here are the steps to reproduce on Ubuntu-Carmic-32bit (g++ v4.4.1)

  1. save example as customExc.cpp
  2. type make customExc.o

EDIT: The error is related to CustomException. The class Foo has nothing to do with it. So I have deleted it.

+3  A: 

Your what() is a const member function, but code() is not.

Just change code() to code() const.

leiz
+2  A: 
   int code() const { return 42; }
Amit Kumar
+3  A: 

Your code() member function is not declared const. Calling non-const member functions from const member functions (what() in this case) is illegal.

Make your code() member const.

AndreyT
that is a pretty opaque error message though...
rmeador
@meador: A **const** on a method means, that **this** will be a pointer-to-const in this method. If you are aware of that, the error message makes perfect sense: when you try to call `code()` from `what()`, you are trying to convert `(const CustomException*) this` into `(CustomException*)this`, thereby discarding the cv qualifier(s) (**const**)
UncleBens
+3  A: 

CustomException::what calls CustomException::code. CustomException::what is a const method, as signified by the const after what(). Since it is a const method, it cannot do anything that may modify itself. CustomException::code is not a const method, which means that it does not promise to not modify itself. So CustomException::what can't call CustomException::code.

Note that const methods are not necessarily related to const instances. Foo::bar can declare its exc variable as non-const and call const methods like CustomException::what; this simply means that CustomException::what promises not to modify exc, but other code might.

The C++ FAQ has a bit more information on const methods.

Josh Kelley
@Josh: Now I got it - and I finally accepted your answer because of the `... what() promises not to modify exc ...`