Post #75,185
1/17/03 3:04:37 PM
|
Fix:
Declare in addition: \n \tinline std::string Address(bool bUseDot = true)\n Notice the missing const. *sigh* I've found other issues with 3.2.1 as well, however. 1) The Amazing Disappearing 'isfinite' #define Macro 2) segfaults if you don't initialize std:strings with "" and so on. So here's what I'm doing: 'apt-get install libstlport4.5' ;-)
Regards,
-scott anderson
"Welcome to Rivendell, Mr. Anderson..."
|
Post #75,214
1/17/03 4:36:06 PM
8/21/07 6:17:22 AM
|
const is a design error
It often leads to amazingly unpredictable behavior or impossible to port code as compilers balk at compiling stuff that isn't exactly entirely const correct.
One possible solution
#define const
Voila is french for "there ya go".
|
Post #75,215
1/17/03 4:38:07 PM
|
One of my directives for this port:
#define DO_NOT_FIX_OLD_CODE_FOR_THE_SAKE_OF_THE_PORT
etc. ;-)
Regards,
-scott anderson
"Welcome to Rivendell, Mr. Anderson..."
|
Post #75,225
1/17/03 5:22:29 PM
|
Re: One of my directives for this port:
I read Stroustrup's explanation of "const" in three different editions of his book, and still didn't really understand it.
-drl
|
Post #75,231
1/17/03 5:42:03 PM
|
The "const" attribute means that, within the given scope,...
the object may not be modified, i.e. for practical purposes is read-only (or constant).
Alex
"No man's life, liberty, or property are safe while the legislature is in session."\t-- Mark Twain
|
Post #75,246
1/17/03 7:31:13 PM
|
Because it's not supposed to be modified...
...i'd suspect that it's also not kosher to dereference a Const pointer. If a dereference is allowed then the program can backdoor a method to change the value by casting it to another type and then doing an assign.
Perhaps that's the point of the error message that Scott received?
|
Post #75,286
1/17/03 10:31:53 PM
|
Yes, I remember all that..
..but why bother? I know what I'm doing when I call a C function - it's pedantic and *against C spirit* to obess on such things.
In the end, you could take BS's approach and make FORTRAN+1 or ADD1TOCOBOL and it would end up violating those languages. He'd have some stupid obession about COMMON blocks in FORTRAN, maybe.
The funny thing is, the early parts of C++ really are improvements to (ANSI) C. It's the bizarre attempts to cover up a fundamentally procedural idiom that gets him into deep shit.
-drl
|
Post #75,300
1/17/03 10:58:51 PM
|
Re: why bother?
Because you don't "own" and may not know the innards of the function you use and the const is part of a compiler enforced interface spec that leads to more predictable code behavior.
When all the code is yours, it does not matter so much. Unless, like me, you may forget what you've done in a couple of weeks.
Alex
"No man's life, liberty, or property are safe while the legislature is in session."\t-- Mark Twain
|
Post #75,304
1/17/03 11:06:45 PM
|
Well, yes, that was what BS was obsessing on
..but why not just make an API with use instructions? If you use it wrong, you will get burned.
CAUTION: Don't use the space heater in a room filled with natural gas.
CAUTION: Remain clear of the blast zone.
CAUTION: Failure to deploy flaps in a timely manner will result in a stall and a fiery metallic death on landing.
CAUTION: Consuming ten times the recommended dosage of this medicine may produce symptoms such as breathlessness, little or no heartbeat, and lack of motivation.
You can't prevent people from being stupid. You have to give them the freedom to be smart.
-drl
|
Post #75,455
1/18/03 6:58:50 PM
8/21/07 6:25:33 AM
|
Clearly BS hates programmers and doesn't trust them
as far as he can throw them. Why else would he work so hard to wrap everything in a straight jacket? Java is kind of that way too but more moderate.
The only thing C++ ought to be used for is purposes for which it was designed. If you're not writing a telephone switching operating system, you don't need it.
I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customer got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.
--Alan Perlis
|
Post #75,472
1/18/03 10:58:42 PM
|
Re: Because it's not supposed to be modified...
ChrisR: i'd suspect that it's also not kosher to dereference a Const pointer.
Huh? A pointer you can't dereference isn't much of a pointer, is it.
There's no problem dereferencing a constant pointer. In fact, arrays in C are (in a certain sense) nothing more than a constant pointer.
ChrisR: If a dereference is allowed then the program can backdoor a method to change the value by casting it to another type and then doing an assign.
Isn't that the whole point of casting in C? :-)
-- -- Jim Weirich jweirich@one.net [link|http://w3.one.net/~jweirich|http://w3.one.net/~jweirich] --------------------------------------------------------------------- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
|
Post #75,221
1/17/03 5:07:46 PM
|
Re: const is a design error
> One possible solution > #define const
Ummm ... That could make some function signatures (that differ only in const) ambiguous.
-- -- Jim Weirich jweirich@one.net [link|http://w3.one.net/~jweirich|http://w3.one.net/~jweirich] --------------------------------------------------------------------- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
|
Post #75,228
1/17/03 5:26:01 PM
8/21/07 6:17:37 AM
|
Only if such differences exist
more often, programmers throw const around here and there without really understanding what its doing. As des said - its not well understood and generally misused.
You may find that definining it away results in less errors than leaving it.
Its a porting trick - sometimes it helps - sometimes not.
I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customer got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.
--Alan Perlis
|
Post #75,357
1/18/03 6:37:38 AM
|
Fun in computing.
I know about that. Many of my favourite moments in my current job are "having fun" with the thing. For instance, I wrote a fortunes module (our product is a groupware product run over an intranet with a web browser). It was nearly as much fun writing it as putting good fortunes in there!
A more productive moment was aggregating a whole heap of functions for drawing HTML form controls into one function. Suddenly they all had the whole range of options and parameter processing that was duplicated incompletety amongst the older functions. That was fun. And doing some very fancy manipulation of school marks for reporting that required PHP arrays of 5 and 6 dimensions. I've had a client ask to see how that works... :-)
Wade.
Is it enough to love Is it enough to breathe Somebody rip my heart out And leave me here to bleed
| | Is it enough to die Somebody save my life I'd rather be Anything but Ordinary Please
| -- "Anything but Ordinary" by Avril Lavigne. |
|
Post #75,468
1/18/03 10:33:25 PM
|
Re: Only if such differences exist
Todd: more often, programmers throw const around here and there without really understanding what its doing. As des said - its not well understood and generally misused.
Really. I've not run into much problems with const, which is, after all, an ANSI C construct and is well entrenched in the ANSI C libraries. I'd be surprised if most C programmers had trouble, otherwise they would constantly run afoul of the standard library.
The problem in C++ is its interaction with overloading, which can be subtl. In fact, the problem Todd is having is more with overloading than with const.
BTW ... I like the Alan Perlis quote. Programming should be fun.
-- -- Jim Weirich jweirich@one.net [link|http://w3.one.net/~jweirich|http://w3.one.net/~jweirich] --------------------------------------------------------------------- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
|
Post #75,554
1/19/03 5:34:48 PM
8/21/07 6:28:10 AM
|
const functions
are the problem. And as you point out - overloading on const (which is pretty lame).
The biggest problem is mixing cost references (I hate references - they suck - use pointers) with objects that aren't exactly const correct (nearly all of them).
People forget to declare methods const - even if they are, and suddenly you're casting away const to get around it. Especially in foreign libraries you don't control the source to.
If C++ were a powertool, OSHA would have made Stroustrup take it off the market.
I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customer got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.
--Alan Perlis
|
Post #75,930
1/21/03 1:53:21 PM
|
Well, it doesnt' appear to be overloaded on const
in fact I'm not sure you can overload on const (I think I tried to at one point).
One function was taking a bool in the sig (defaulted to true) and the other a char *.
I think (but am not sure) that the problem was that the function itself was const (on one sig) and in the other it wasn't, but I'd have to prototype to verify.
BTW: I do agree with your other statements however. Beware programmers that overly use const, as it becomes a REAL pain to get around them later.
|
Post #75,948
1/21/03 3:47:40 PM
|
Re: Well, it doesnt' appear to be overloaded on const
Beware programmers that overly use const, as it becomes a REAL pain to get around them later.
There are two ways to work with const ...
1) Never use const ...
2) Always use const where appropriate ...
In both cases you run into problems with libraries that did it the other way. I tend to fall into category 2.
-- -- Jim Weirich jweirich@one.net [link|http://w3.one.net/~jweirich|http://w3.one.net/~jweirich] --------------------------------------------------------------------- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)
|
Post #75,963
1/21/03 4:13:33 PM
8/21/07 6:37:06 AM
|
No, thats exactly the problem
It works like this:
class List { public: void addItem(int i) { /* do add */ } void addItem(int i) const { throw new ConstListException(); } }
List* list = new List(); const List* clist = list;
list.addItem(i); // fine - adds an item clist.addItem(i); // throws an exception because const version is invoked
IOW, if you define a member function and you don't make it const, then you can't call it using a const ref to the object.
If you define a member function and make it const, you can call it with both a const and non-const ref to the object.
If you define both a non-const and const version of the same function, the const version is called when you have a const ref to the object and the non-const version is called with non-const refs.
As developers aren't particularly good judges on what is const and what isn't const, this "feature" has turned out to be a PITA.
------
There is a different approach that was employed in ObjectiveC.
The collection classes (which is usually the issue anyhow - do you return a new copy or a reference to private data?) are defined at two levels.
NSArray, NSDictionary, and NSSet have read-only semantics. No mutators are defined in these classes. So they are effective immutable. NSMutableArray is a subclass of NSArray and adds mutator methods (those that you wouldn't declare const). Same with NSDictionary and NSSet, mutable subclasses exist.
Suppose I have a class Artist with an array of Paintings.
@interface Artist { NSMutableArray* _paintings; }
-(void)addPainting:(Painting*)p { [_paintings addObject: p]; } -(void)removePainting:(Painting*)p { [_paintings removeObject: p; } -(NSArray*)paintings { return _paintings; } @end
Notice that when asked for the list of paintings, I say I return the superclass type NSArray. Its private data, but if you try to send it a mutator method, the compiler will warn you that this is not cool (but it'll still do it).
Thus, I get out of copying the collection and still keep it from being modified. (They could downcast - but downcasting is evil and thus they deserve what they get for that).
Simple two level design idea. C++'s const mechanism tries to do the same thing, but its more confusing to use and I think it fails because its confusing.
I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customer got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.
--Alan Perlis
|
Post #75,992
1/21/03 5:42:24 PM
|
This is what bugs me in Scott's problem...
>>>>>>>>>>>>> If you define a member function and make it const, you can call it with both a const and non-const ref to the object. <<<<<<<<<<<< He has a const member function. There is really no conversion involved in calling const function on non-const reference. What the hell does compiler want from the poor guy? One more thing. In this code: \nclass OtherClass\n{\npublic:\n\n\tbool Address(const char *address);\n\n\tinline std::string Address(bool bUseDot = true) const ;\n};\n\n\nvoid tryThis()\n{\n OtherClass m_addr;\n\tstd::string m_server_address = m_addr.Address(false/*replace here*/);\n}\n\n If I replace "false" in tryThis() with "true", it compiles fine. Could GCC be trying to interpret "false" as NULL? Dumb, I know.
--
We have only 2 things to worry about: That things will never get back to normal, and that they already have.
|
Post #76,023
1/21/03 9:43:01 PM
|
I was pissed enough at the problem
I hacked gcc code to report on what conversions take place. Here is the code I used for testing: \nclass OtherClass\n{\npublic:\n\n bool Address(const char *address);\n\n inline const char *Address(bool bUseDot = true) const ;\n};\n\n\nvoid tryThis()\n{\n OtherClass m_addr;\n const char *m_server_address = m_addr.Address(false);\n}\n Works just as badly as the original. Here is the debug output: \ng++ -c test.cpp\ntest.cpp: In function `void tryThis()':\ntest.cpp:25: warning: from "OtherClass*" "&m_addr"to "const OtherClass*" using\ntest.cpp:25: warning: qual_conv\ntest.cpp:25: warning: identity_conv\ntest.cpp:25: warning: &m_addr\n\ntest.cpp:25: warning: from "bool" "false"to "bool" using\ntest.cpp:25: warning: identity_conv\ntest.cpp:25: warning: false\n\ntest.cpp:25: warning: from "OtherClass*" "&m_addr"to "OtherClass*" using\ntest.cpp:25: warning: identity_conv\ntest.cpp:25: warning: &m_addr\n\ntest.cpp:25: warning: from "bool" "false"to "const char*" using\ntest.cpp:25: warning: std_conv\ntest.cpp:25: warning: identity_conv\ntest.cpp:25: warning: false\n\ntest.cpp:25: choosing `const char* OtherClass::Address(bool) const' over `bool\n OtherClass::Address(const char*)'\ntest.cpp:25: because worst conversion for the former is better than worst\n conversion for the latter\n\nCompilation exited abnormally with code 1 at Tue Jan 21 21:31:05\n So, it takes 2 conversions to go from false to (const char *) Here are relevant paragraphs from [link|http://www.comnets.rwth-aachen.de/doc/c++std/conv.html|C++ standard:] >>>>>>>>>>>>>>>>>>>>>>> 1 Standard conversions are implicit conversions defined for built-in types. The full set of such conversions is enumerated in this clause. A standard conversion sequence is a sequence of standard conversions in the following order: --Zero or one conversion from the following set: lvalue-to-rvalue con- version, array-to-pointer conversion, and function-to-pointer con- version. --Zero or one conversion from the following set: integral promotions, floating point promotion, integral conversions, floating point con- versions, floating-integral conversions, pointer conversions, pointer to member conversions, and boolean conversions. --Zero or one qualification conversion. [Note: a standard conversion sequence can be empty, i.e., it can con- sist of no conversions. ] A standard conversion sequence will be applied to an expression if necessary to convert it to a required des- tination type. ........ 4 An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true becoming one. ......... 1 An integral constant expression (_expr.const_) rvalue of integer type that evaluates to zero (called a null pointer constant) can be con- verted to a pointer type. The result is a value (called the null pointer value of that type) distinguishable from every pointer to an object or function. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (_conv.qual_). <<<<<<<<<<<<<<<<<<< So, GCC is right. And I have to concede: C++ is a sick language. However, the correct conversion should still be picked by comparing length of path for 2 possibilities. The text that Scott saw on screen was a "pedantic warning" - something less than a regular warning. It should never fail the compilation. I'll try to find out why the exit code is 1 after that "pedwarn".
--
We have only 2 things to worry about: That things will never get back to normal, and that they already have.
|
Post #76,031
1/21/03 10:37:18 PM
|
I was pissed enough that I:
Switched to 2.95.4 with stlport, which works "wonderfully" (read: sufficiently crummy version of wonderful as defined by the C++ spec) as compared to 3.2.1.
Regards,
-scott anderson
"Welcome to Rivendell, Mr. Anderson..."
|
Post #76,038
1/21/03 11:23:30 PM
|
Solution
`-fpermissive' Downgrade messages about nonconformant code from errors to warnings. By default, G++ effectively sets `-pedantic-errors' without `-pedantic'; this option reverses that. This behavior and this option are superseded by `-pedantic', which works as it does for GNU C.
I think GCC is no less fucked than C++ standard. But at least you can make it swallow the code.
--
We have only 2 things to worry about: That things will never get back to normal, and that they already have.
|
Post #76,039
1/21/03 11:24:50 PM
|
ROFL
But at least you can make it swallow the code. gcc: the compiler that swallows, not spits.
Regards,
-scott anderson
"Welcome to Rivendell, Mr. Anderson..."
|
Post #76,119
1/22/03 11:08:55 AM
|
Re: "..you can make it swallow the code." Beautiful!
Alex
"No man's life, liberty, or property are safe while the legislature is in session."\t-- Mark Twain
|