List<> of struct with property. Cannot change value of property. why?

B

Ben Voigt

Sorry about not compile-testing.

Here is an example that may work better for you:

/* in one compilation unit */
namespace { std::vector<int> v; }
void stuffit(int& n)
{
v.push_back(n);
}

/* in another compilation unit, assuming that the proper prototype for
stuffit is available */
int main()
{
for( int i = 0; i < 4; i++ ) {
stuffit(i);
}
return 0;
}

Without "const", no optimizations are possible. With "const int& n", the
compiler can fully unroll the loop and eliminate i. Yes, I know that
passing an int by const reference in this case is silly, but it could easily
be a large data structure, and stuffit could be an arbitrary level of
complexity.

Or:

void demo(int i)
{
int a[10];
for( int j = 0; j < 10000; j++ )
{
a[13 * i % 7 + 3] += j;
stuffit(i);
}
}

With "const int& n", the compiler can determine that i is unchanging for the
duration of the loop, and by extension, the pointer a + 13 * i % 7 + 3 can
be pre-computed (and in fact the entire addition operation could be
pre-evaluated as 10000 * 10001 / 2 => 50005000). Without "const", aliasing
analysis reveals that i can change, therefore the computation must be
executed inside the loop, with little opportunity for optimization.

And the const on a member function is equivalent to changing constness of
the 'this' parameter, so all the above applies.
 
B

Ben Voigt

As applied to function declarations, I don't see how "const" enables any
of those optimizations. The compiler can't rely on the "const" keyword,
because it can always wind up being cast away.

I absolutely disagree with this. The onus is on the programmer not to cast
away const in any way that would make the compiler's optimizations incorrect
which rely on said const-ness. Practically speaking, casting away const is
always an error, now that C++ has the mutable keyword. But certainly the
compiler can and does rely on the const keyword, and you take your (process)
life in your hands when you cast it away.
 
B

Ben Voigt

Peter Duniho said:
[...]
But, for C#, the warning would only come up when you're potentially
modifying a temporary. Usually you don't even want to be calling a
method AT ALL on one, so I don't think the warning would happen too
often when it shouldn't (but that's based on my limited experience).

I disagree that you would never want to call a method on a temporary
value. In fact, because of the OOP nature of C#, you are almost always
calling a method, if you are using a temporary value at all.

If anything, I could see adding a warning when you are modifying a public
field of a value type that is a temporary instance. That seems obviously
unwise and reasonable for the compiler to complain. But for methods, the
method could be doing anything, and the compiler doesn't really know what
that is. In fact, for a well-designed value type (eg immutable), a method
on a value type would *always* be safe on a temporary value.

And an immutable value type would only have methods declared const, so
safety is properly noted by the compiler.
 
B

Ben Voigt

Peter Duniho said:
Been there, done that. In any sizable project, you can waste a whole day
chasing down warnings and still not find all the places you need to add
"const".

And even when you spend that time, frequently you reach a point where
you're calling some third-party API that you don't have the freedom to
change. At that point, if the language doesn't allow you to cast away

And that impeaches the design of said API and should seriously call into
question your decision to use it. If a library designer can't get
const-correctness, how can they be expected to properly solve a bunch of
more devious concerns (parameter checking, buffer overflows, race
conditions, etc)?

const-ness, you're stuck. And allowing you to cast away const-ness
significantly lessens the usefulness of "const", IMHO.


What do you do when you don't have control over the design that is causing
you trouble?

You let your boss know that the design has fundamental flaws, and be
thankful that const brought these to your attention before deploying said
flawed design in a critical scenario and maybe killing someone.
No, I wouldn't want things to change depending if it had const-ness or
not! It could just be used for a helpful warning, that's all: Why
call a method that changes the class when the class is a temporary,
and is thrown away before you can even see or use it?
[...]

I *meant* to say 'struct' / value type, instead. I'll try to be more
clear in the future.

Okay...well, I can agree that calling a method that changes a struct when
the struct is temporary isn't useful. But how to implement this in a
practical way is the question.

Pete
 
P

Peter Duniho

And that impeaches the design of said API and should seriously call into
question your decision to use it.

You mean, like the Windows API?

I suppose I could avoid writing Windows software, but...that severely
restricts my market.

Pete
 
B

Ben Voigt

Peter Duniho said:
You mean, like the Windows API?

You're going to have to be far more specific -- there are a lot of different
libraries grouped under the heading of "the Windows API" and all the core
ones are const-correct, in my experience.

If you find a Windows API function that isn't const-correct, then yes, I
would avoid that library and re-implement the required functionality using
the core APIs (or find a solution that has already done so, in a trustworthy
manner).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top