Re: strange compiler message
From: Tobias Güntner (fatbull_at_users.sourceforge.net)
Date: 08/11/04
- Next message: Peter Olcott: "Re: Yet another Attempt at Disproving the Halting Problem"
- Previous message: Bob Hairgrove: "Re: Return an iterator?"
- In reply to: Neil Zanella: "Re: strange compiler message"
- Next in thread: Neil Zanella: "Re: strange compiler message"
- Reply: Neil Zanella: "Re: strange compiler message"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 11 Aug 2004 01:20:05 +0200
Neil Zanella wrote:
> Not confusing: in C and C++ it is illegal to modify string literals, thus,
> even if the programmer were sloppy enough not to check the function signature,
> the programmer would still know that " blah blah " would not get modified.
That doesn't really matter... This literal could be hidden through some
preprocessor variable, a const buried in some headers or a return value
from some other function. It's just one out of a million comparable cases.
Fortunately the compiler will detect the error, no matter why the
programmer wrote such code (maybe he/she is a beginner and doesn't know
better?)
> Furthermore, your example is not a good one because the following code is
> legal according to the C++ standard,
no, it's not. see below.
> but according to your point of view
> still more confusing than the illegal code you posted: here we have
> a pointer to dynamically allocated memory. If the programmer doesn't
> check the function signature, then, according to your point of view,
> the programmer might think trim_whitespace() may call realloc on
> blah (which it doesn't, since it takes an str, hence must call
> construct a separate string first).
That's what I'm trying to explain. And there are many more cases where
the error is not so obvious. Again: Because implicit conversions are
performed, even you might involuntaryly write such code. If you really
want the "wrong" (or "unobvious") behavior, you can still explicitly say so.
> void trim_whitespace(string& str);
> int main()
> {
> char *blah = malloc(12);
> strcpy(blah, " blah blah ");
> trim_whitespace(blah);
> return 0;
> }
This code is illegal and should not compile for two reasons:
1) malloc returns void* which cannot be converted to char* (but I guess
it's just a typo)
2) in the call to trim_whitespace, a temporary std::string has to be
constructed and bound to a reference to non-const string. Constructing a
string is allowed, but binding the temporary string to a reference to
non-const is not (see 13.3.3.1.4/3).
Actually the standard also says that references to non-const cannot be
bound to r-values [13.3.2/3], but IMHO that's more or less the same in
our context (although I'm not a language lawyer ;) )
>>The point is: Because implicit conversions are performed, you might
>>*involuntaryly* pass a temporary object to a function that is supposed
>>to modify the original object.
>
>
> So according to your point of view, why is the modified
> I posted allowed by C++? All you said applies to the
> modified code snippet I posted as well.
As I said, it's _not_ allowed and you've provided a nice example that
shows why it isn't allowed ;)
>>Usually you pass objects to a modifying function because you really want
>>it to modify an object, don't you?
>
>
> Not true. Think about OpenGL where you must necessarily use globals to
> save and restore state. Also, think about programs where you pass in an
> object and the function returns another one (instead of being a void one
> like the one in the example I gave). Think of all those functions that
> take CONST references. There is no usually: it depends.
You've lost me here... What do you mean by this? That const-correctness
is not as widely spread as it should be?
>
>
>>>since the object is temporary, the programmer will never have a
>>>chance of accessing it ever again
>>
>>Exactly! Now tell me: Why should I call that function if I never use its
>>results?
>
>
> Because we often don't need to modify what we pass in or use it again at all:
>
> void foo(const int i) {
> if (i == 0)
> std::cout << "hello" << std::endl;
> else
> std::cout << "good night" << std::endl;
> }
>
> int main() {
> foo(0);
> foo(1);
> }
I was talking about the case where foo takes an int&
void calc(int& result) {
result = /* some calculation */;
// the only visible effects of calc() are
// the effects caused to the result parameter
// calc does not modify any global variables,
// do I/O, etc. or call other functions that might do
}
int main()
{
// let calc() do something, but I don't care for the result
// If the compiler is smart enough, it will optimize the
// entire function call away - What has been gained by
// this function call? Why did the programmer do this?
calc(int());
// some class that provides operator int()
convertible_to_int not_an_int;
// ...
calc(not_an_int);
// not_an_int is unchanged - is this really the intent?
// Did the programmer really want to write a do-nothing statement?
}
>>(and I'm not talking about error return codes here)
>>Why call a function that has absolutely no side effects? (or more
>>exactly: whose side effects vanish immediately after the function has
>>returned?)
>
>
> ??? Obviously, you have narrowed your view to a particular class of functions.
because IMHO the restriction has been placed to prevent subtle bugs that
can only occur under very specific circumstances.
There is no problem with functions that take references to const - It
clearly states "dear function, take this object and do with it what you
like, but don't change it", whereas reference to non-const says "take
this object and do with it what you like; you may even change it".
In the latter case, the compiler cannot be sure if the programmer wanted
to modify a) the original object or b) the temporary object that had to
be created for conversion. These two things are completely different!
- Next message: Peter Olcott: "Re: Yet another Attempt at Disproving the Halting Problem"
- Previous message: Bob Hairgrove: "Re: Return an iterator?"
- In reply to: Neil Zanella: "Re: strange compiler message"
- Next in thread: Neil Zanella: "Re: strange compiler message"
- Reply: Neil Zanella: "Re: strange compiler message"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|