www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - A const use-case I would NOT like to see replicated

reply Tim Keating <holyspamster gmail.com> writes:
I have been following the discussion on const/invariant/final, and while 
I understand the need to add this feature to the language, my initial 
reaction was repugnance. In order to add value and not just fan a 
flame-war, I spent some time ruminating on why this is so. As a result, 
I recalled a use case for const in C++ that caused me considerable pain, 
and so I throw it out here for discussion.

My main issue is with const-correct programs passing data to 
non-const-correct libraries. For example, consider extracting string 
data from a std::string to pass to a library written in C (using the 
c_str() member func). If the function you want to call takes a const 
char*, as it should, then great, you're fine. If it takes only a char* 
(which I have seen happen plenty of times), you're screwed. Your choices 
are:

1) Fix the function. Even if you *can* do this (i.e the library is not 
open-source, or in a legacy library that you're forbidden to modify, or 
part of the fastest linker in the world that no one understands anymore 
and you don't dare update), it could well be that making the function 
argument const will break too much dependent code to make it 
realistically feasible.
2) Cast away the constness, perhaps in a wrapper function. Yuck, 
basically. Casting away constness should only rarely be necessary, if 
ever. This is too common a use case for that to be the standard behavior.
3) Dupe the function and make a const flavor of it. This isn't 
*terribly* egregious if the function doesn't change very often, but if 
it has to be maintained you're asking to get bitten by a subtle bug.

Either there should be a simple, idiomatic solution to this problem, or 
(if possible) the compiler should determine whether the const reference 
is modified by the called function. If not, it should allow you to pass 
the const reference. In other words: although the const type attribute 
is a guarantee that a function WILL NOT modify your data, its absence 
should not automatically imply that the function WILL modify your data.

I'm not a compiler writer. I don't know whether doing that is hard, or 
even feasible. But there's my $0.02.

TK
Jun 21 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Tim Keating wrote:
  My main issue is with const-correct programs passing data to
 non-const-correct libraries. For example, consider extracting string 
 data from a std::string to pass to a library written in C (using the 
 c_str() member func). If the function you want to call takes a const 
 char*, as it should, then great, you're fine. If it takes only a char* 
 (which I have seen happen plenty of times), you're screwed. Your choices 
 are:

Having const can certainly lead to lots of casts here and there when working with code that isn't const aware. No question about that. But the casts are there for a reason -- they're reminding you and other programmers that come along later "this is a potentially unsafe operation". Ok, but I can see that it might be nice to have a way to import a module such that it ignores const issues. Like casting away const on all the functions in a module with one line of code. Like Don's "break const" -- something like break(const) import legacy_module; I think this could be tricky to implement though. --bb
Jun 21 2007
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Tim Keating wrote:
 I have been following the discussion on const/invariant/final, and while 
 I understand the need to add this feature to the language, my initial 
 reaction was repugnance. In order to add value and not just fan a 
 flame-war, I spent some time ruminating on why this is so. As a result, 
 I recalled a use case for const in C++ that caused me considerable pain, 
 and so I throw it out here for discussion.

I think you've run into the well known problem that you cannot do const-correctness halfway. Once you start using const, it has to be used throughout your program or library. A corollary is it is not very practical to have a const-correct program that calls a library that is not const-correct. The general conclusion is: 1) If you're writing a general purpose library, you have to make it const-correct, otherwise your users will curse you and your little dog, too. 2) If you're writing a program, you can successfully ignore const. But if you do start using const, you'll find you have to commit to using it throughout. As part of 2.0, I therefore had to go through Phobos to make it const-correct. I found a couple of cases where I didn't remember if an input value was modified or not, and had to spend a non-trivial amount of time figuring it out. This gave me a bit of a better appreciation for the documentation benefits of const-correctness. Another point of note - I didn't find a single bug in Phobos from doing the conversion.
Jun 21 2007
parent James Dennett <jdennett acm.org> writes:
Walter Bright wrote:
 Tim Keating wrote:
 I have been following the discussion on const/invariant/final, and
 while I understand the need to add this feature to the language, my
 initial reaction was repugnance. In order to add value and not just
 fan a flame-war, I spent some time ruminating on why this is so. As a
 result, I recalled a use case for const in C++ that caused me
 considerable pain, and so I throw it out here for discussion.

I think you've run into the well known problem that you cannot do const-correctness halfway. Once you start using const, it has to be used throughout your program or library. A corollary is it is not very practical to have a const-correct program that calls a library that is not const-correct. The general conclusion is: 1) If you're writing a general purpose library, you have to make it const-correct, otherwise your users will curse you and your little dog, too. 2) If you're writing a program, you can successfully ignore const. But if you do start using const, you'll find you have to commit to using it throughout. As part of 2.0, I therefore had to go through Phobos to make it const-correct. I found a couple of cases where I didn't remember if an input value was modified or not, and had to spend a non-trivial amount of time figuring it out. This gave me a bit of a better appreciation for the documentation benefits of const-correctness. Another point of note - I didn't find a single bug in Phobos from doing the conversion.

Yes you did; you documented one above (unless you consider documentation defects not to be "bugs")! -- James
Jun 22 2007