Pregunta

Say I have the following member function:

void CFoo::regWrite( int addr, int data )
{
  reg_write( addr, data ); // driver call to e.g. write a firmware register
}

Clearly, calling this function doesn't modify the internal state of the object it is called on. However, it changes the state of whatever this Foo instance represents.

In circumstances such as these, should Foo::regWrite(int addr, int data) be a const function?

¿Fue útil?

Solución

You have to decide what the meaning is of "logically const" for the class CFoo, and that depends what the class is for.

If CFoo is construed as referring to some data, then it might make sense to be able to modify that data via a const instance of CFoo, in which case your member function would be const. For examples of this consider other types that refer to some data -- you can modify the referand of a char *const or a const std::unique_ptr<char>.

If CFoo is construed as owning some data, then it might make sense to forbid modification via a const instance of CFoo. For examples of this consider containers, where the elements are logically "part of the object's state" even when they aren't physically part of the object. So vector::operator[] has a const overload that returns a const T& rather than a T&, the insert member function is non-const, etc.

Otros consejos

It is up to the programmer to define what 'const' shall mean for a class. With the specifier mutable you can even have a constobject with changing values in a member. When it comes to hardware one might consider the configuration as the target for const correctness: as long as the configuration does not change the object can be considered constant.

A similar issue rises if you have pointers to other objects in your class: Your const method can then call non-const methods on the other object and thus modifiy it.

If you look at the hardware as as some other object referenced by your class, it would be perfectly valid to modify firmware settings (since only a "referenced" object is changed). If you want your class to "represent" the hardware (or part of it), I would rather suggest not to mark the method as const.

So I think it mainly depends how you designed your class.

There are two ways of looking at this - the optimization angle, and the logic of this declaration. Which is more important is for you to decide.

Optimization

EDIT: I made some incorrect assumptions. It seems the compiler is not actually free to make the optimizations below, and will only make them by analyzing the body of the method to ensure no modifications occur (and even then only in simple cases).

Having this const will allow the compiler to optimize a little bit more. It knows that regWrite doesn't change any fields in the object, so it can keep them if it was storing them in registers, and do similar optimizations that rely on the objects fields not being changed.

This is really the only thing the compiler will depend on when you make a definition like this, so having this const is OK and can theoretically allow better performance.

Making logical sense

It feels unintuitive to have a const method whose whole purpose is a destructive change. The usual intuition a programmer has is that as long as I'm only calling const methods, the results of other const methods shouldn't change. If you violate this unwritten contract, expect people to be surprised - even if the compiler is OK with it.

I'm not sure if this will be violated here - it will depend on the other code in this class. However, if no other considerations are important (performance, etc.), const is (for me) mostly a marker on the interface which says "calling this does not change the state of this object", for a broad definition of "state".

This is murky ground however, and it is up to you what you consider a state change. If you think of your firmware object as representing a link to the internals, writing a register does not change anything about this link and is const. If you think of it as representing the state of the underlying registers, than writing to registers is a change of state.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top