4

I was experimenting with the const keyword and trying to get an useful approach from it.

#include <iostream>

class A
{
  public:
  static const void modify(float& dummy)
  {
    dummy = 1.5f;
  }  
};

int main(int argc, char* argv[])
{
  auto a = 49.5f;

  A::modify(a);

  std::cout << a << std::endl; 

  return(0);
}

this code compiles and works, the output is 1.5, I was expecting an error from the compiler because I have a const method that is trying to modify the value of an argument.

What I'm missing here ? How i can design methods that will not modify argument's values?

user1802174
  • 273
  • 3
  • 10
  • Huh, I didn't know you could apply `const` to `void`. – chris Nov 09 '12 at 06:01
  • actually you mean static const void modify(const float& dummy)? in this case, you can't modify dummy – billz Nov 09 '12 at 06:02
  • @chris How i can write a similar method that can keep my arguments constant ? why I don't get the warning ? – user1802174 Nov 09 '12 at 06:02
  • Hey, look what I get from GCC: *warning: type qualifiers ignored on function return type [-Wignored-qualifiers]* – chris Nov 09 '12 at 06:02
  • @billz yes, but my doubt is about the use of const for the type of the method itself. – user1802174 Nov 09 '12 at 06:03
  • @user1802174, `const` only applies to the thing next to it. – chris Nov 09 '12 at 06:04
  • @chris I get absolutely nothing with `g++-4.7 -std=c++11` – user1802174 Nov 09 '12 at 06:04
  • @user1802174, It's probably part of `-Wall` or `-Wextra`. – chris Nov 09 '12 at 06:05
  • @chris so there is no way to use const on void methods ? – user1802174 Nov 09 '12 at 06:05
  • @user1802174, It only applies to the `void` part, which is completely useless, since you can't do anything with `void` anyway. There's no general syntax for making each parameter constant. You have to manually apply it to each one. – chris Nov 09 '12 at 06:06
  • @chris "since you can't do anything with void anyway." well not really because the point of making every method const is to get this kind of warning and with a void I can do the same mistakes that i can do with all the other signatures ... – user1802174 Nov 09 '12 at 06:08

2 Answers2

5
  1. The method you declared is not const. It returns a const void (whatever that is), but it is not a const-method itself.

  2. If it were declared

    void modify(float& dummy) const
    

    it would be a const-method, but then still it could modify the value of the argument, because a const-method is allowed to do this. The only thing it is not allowed to do is to modify values of members of the class it belongs to.

  3. Note that in order to declare a const method, I had to remove the static specification. A static method can never be const, because a static method can't modify any members anyway.

  4. If you want to prevent the function from modifying its argument, you'd have to make the argument const:

    static void modify(const float& dummy)
    

To illustrate what a const-method can and cannot do, here is a class that has a member, and a const-function:

class A
{
  float my_member;
public:
  void modify(float& dummy) const
  {
    my_member = dummy; // attempt to modify member -> illegal
    dummy = 1.5f;      // modifies a non-const argument -> ok
  }  
};

As you can see, it cannot modify a member, but it can modify the value of its argument. If you want to prevent that, you need to make the argument const:

class A
{
  float my_member;
public:
  void modify(const float& dummy) const
  {
    my_member = dummy; // attempt to modify member -> illegal
    dummy = 1.5f;      // attempt to modify a const reference -> illegal
  }  
};
jogojapan
  • 68,383
  • 11
  • 101
  • 131
  • so the point 4 is the only solution for this and all the void methods ? – user1802174 Nov 09 '12 at 06:10
  • No its to prevent argument modifying. – Denis Ermolin Nov 09 '12 at 06:11
  • 1
    @user1802174, It's the only solution for every function. The return type has nothing to do with it. – chris Nov 09 '12 at 06:11
  • @chris i was convinced that the use of const could put every argument in a safe. probably it's not ... – user1802174 Nov 09 '12 at 06:14
  • @user1802174, It can individually, but there's really no place to put it that won't be ambiguous with something else anyway. – chris Nov 09 '12 at 06:16
  • I had the same reaction about 'const void' - not sure what that is supposed to be. Since 'const void' it's almost always likely to be a mistake, I would hope that a reasonable compiler would warn, but this doesn't seem to be the case. – Nik Bougalis Nov 09 '12 at 06:32
  • @NikB. As (almost) always when we are puzzled by something, somebody was puzzled before: http://stackoverflow.com/questions/5057987/whats-the-point-of-const-void – jogojapan Nov 09 '12 at 06:34
  • 1
    I know, I wasn't puzzled; it makes good sense to not define a special case for 'const void' in the standard. But that doesn't mean that compilers shouldn't warn for something like that, even if strictly speaking, it's "standards compliant". – Nik Bougalis Nov 09 '12 at 06:37
1

You are misunderstanding what 'const' does in this case and how it operates.

First of all, in C++ static member functions cannot be const. The function you show returns a type of 'const void' (whether this makes sense and whether the compiler should warn is another topic).

Second of all the parameter you are changing isn't const. If 'modify' wasn't a static function and had a 'const' modifier on the function, dummy could still be modified:

void modify_nonstatic(float &dummy) const
{
    dummy = 1.5f; // perfectly fine - dummy isn't a member of
                  // the class and can be modified
}

If you want the parameter to be const, make the parameter const:

static void modify(const float &dummy) 
{
    dummy = 1.5f; // fail! you can't modify a const.
}

void modify_nonstatic(const float &dummy)
{
    dummy = 1.5f; // fail! you can't modify a const.
}
Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37