5

I have this code:

#include <stdio.h>

class A
{
public:
  int doit()
  {
    return 5;
  }
  int doit2() const
  {
    i++;
    return i;
  }
  int i;
};

int main()
{
  A a;
  printf("%d\n", a.doit() );
  return 0;
}

Which compiles cleanly with g++ -Wall -Wpedantic main.cpp. Is there some way to get g++ to say "A::doit() should be marked as const"? g++ 4.8 has -Wsuggest-attribute=const but it doesn't seem to work in this case. g++ -Wall -Wpedantic -Wsuggest-attribute=const const_main.cpp -fipa-pure-const -O2 -Wextra is still clean.

I agree that const is a design decision but what I'm dealing with is a case of many lines of legacy code and for new developers coming in it would be helpful if const functions were marked as such. I think the compiler knows enough because if I mark a function as const and then modify state it will throw an error. I'm just asking for the opposite of that so that I can rip through and mark const functions as const and I don't even need it to be perfect and figure out really complicated cases, I would settle for the simple cases as I have outlined in the code above.

Now I added a non-const function doit2() but declared it const and the compiler says:

const_main.cpp: In member function ‘int A::doit2() const’:
const_main.cpp:12:6: error: increment of member ‘A::i’ in read-only object
     i++;
      ^

I just need the opposite of that ( tell me when it could be const but it isn't marked as such ).

Found the answer over here: Const correctness warnings c++

Community
  • 1
  • 1
user3642186
  • 179
  • 5

3 Answers3

5

No. Designing an interface is not just about allowing current behaviour - it's also about reserving freedoms and expressing limitations so the client code isn't broken by future changes to your class's code. It's not reasonable for gcc to expect that doit() should be const, as some intended or envisaged evolution of the code may require it to be non-const... you are responsible for expressing this design decision. Test cases can help to ensure intended and only intended operations are allowed, but again the test cases will be a reflection of your design decision about client usage, and not something decided by the compiler.

A very simple example is a function with an initial implementation ala throw Not_Implemented(); - the throw suggests no need to be non-const, but if the logical operation the function requests is eventually implemented and would need to change the observable object state, then it should be not be initially marked const. std::string::shrink_to_fit() is a similar example - it might be empty and therefore potentially const when unimplemented (the Standard says it's a non-binding request), but should be non-const because when implemented it changes the observable state of the object (e.g. future iterator invalidation during actions that may now trigger an earlier resize()).

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • I don't buy your reasoning. You can *expect* something to be true even if it may not be true in a minority of cases. I think it's safe to say that if a non-virtual function doesn't modify any state, there's a 90% chance that it should be const. – user541686 Aug 28 '14 at 02:30
  • @Mehrdad: my point is that there will be significant numbers of false positives... in a large project as a regularly used warning flag, that would get on a lot of people's nerves, but sure - there's obviously potential interest/utility for occasional checks of this type - probably suitable for a tool like `cppcheck` more than `gcc`. – Tony Delroy Aug 28 '14 at 04:18
  • Isn't that the case with a lot of warnings? On large projects they are bound to give false positives, but people still find them useful regardless. – user541686 Aug 28 '14 at 04:28
  • @Mehrdad: the question is "How can I find C++ functions that should be const?" - the answer is *you can't*. Reasons for that above. The question's text - after recent edits - clarifies an interest in a diagnostic regardless while fully acknowledging how dodgy that is... fair enough, gcc either does it or it doesn't and our opinions of whether it should bother is now known but probably of little interest to anyone... right now it seems the OP's been unable to get `-Wsuggest-attribute` to work, so re "Is there some way to get g++ to say "A::doit() should be marked as const"?" - still "no". – Tony Delroy Aug 28 '14 at 05:20
1

How can I find C++ functions that should be const?

It's simply about detecting, if you're changing any state of members in this (class) scope or not. Also exposing references or pointers that allow changing state of class member variables isn't valid for const function members.

And: No there's no way this is done automatically, you'll have to mark those functions as const manually, and let the compiler tell you if the body's code violates this constraint.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 1
    +1 Because this is the correct answer and is very simple & straight-forward to understand. `TLDR`: "If your function modifies anything (variables/members) within your class, don't mark it const.. otherwise mark it const." – Brandon Aug 28 '14 at 02:44
0

Now I added a non-const function doit2() but declared it const and the compiler says: increment of member ‘A::i’ in read-only object

This is because you're trying to modify a member variable inside a const function. A const function is a pure observer function that doesn't change the state of the object and thus when you try to change state in such a function the compiler complains.

Inside a const function, all the member variables, irrespective of whether they're declared const or not, will have the const qualifier applied. The exception to this rule are the ones declared mutable.

legends2k
  • 31,634
  • 25
  • 118
  • 222