Re: strange compiler message
From: Neil Zanella (nzanella_at_cs.mun.ca)
Date: 08/13/04
- Next message: Bernd Danberg: "main argv command line"
- Previous message: Will Twentyman: "Re: Yet another Attempt at Disproving the Halting Problem"
- In reply to: Tobias Güntner: "Re: strange compiler message"
- Next in thread: Tobias Güntner: "Re: strange compiler message"
- Reply: Tobias Güntner: "Re: strange compiler message"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 13 Aug 2004 11:13:15 -0700
Tobias Güntner <fatbull@users.sourceforge.net> wrote in message news:<cfbl36
> > 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)
You're right, this in fact seems to be one difference between C and C++:
In C you can say "char *blah = malloc(12);",
but in C++ you must explicitly use a cast or
the compiler will complain.
> 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 ;) )
I see what you mean now: consider the following code:
#include <iostream>
#include <cstring>
#include <string>
void foo(std::string &str) { // not allowed because C++ won't convert a
// temporary to a nonconst reference on a
// function call: must use the following
// signature instead
//void foo(const std::string &str) {
std::cout << str << std::endl;
}
int main() {
char *blah = static_cast<char *>(malloc(22));
strcpy(blah, " blah blah ");
foo(blah);
}
When I use the wrong signature the compiler issues the following error:
$ g++ hello.cpp
hello.cpp: In function `int main ()':
hello.cpp:16: could not convert `blah' to `string &'
hello.cpp:5: in passing argument 1 of `foo (string &)'
> As I said, it's _not_ allowed and you've provided a nice example that
> shows why it isn't allowed ;)
Thanks. ;)
> 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!
In other words it's all there to prevent programming errors due to the
programmer not checking signatures: to prevent the situation where the
programmer expects the passed in parameter to be modified when in fact
something constructed from it ends up being modified.
All of this because C++ introduces the concept of calling a constructor
on a parameter to a function. The fact that such constructor may
do a copy on the passed in argument means that the resulting
constructed object may not alter the origninal object when
acted upon by some code.
Fair enough. It seems like nothing more than a design decision.
The following is legal because it does not make use of the
"construction on function call" as described above.
#include <iostream>
#include <cstring>
#include <string>
void foo(std::string &str) {
std::cout << str << std::endl;
}
int main() {
char *blah = static_cast<char *>(malloc(22));
strcpy(blah, " blah blah ");
std::string s(blah);
foo(s);
}
The following is also disallowed, by design decision: the C++ designers
figured that since a temporary is being passed in good coding practice
dictates that the programmer ought to be make foo const. (?)
#include <iostream>
#include <cstring>
#include <string>
void foo(std::string &str) {
std::cout << str << std::endl;
}
int main() {
char *blah = static_cast<char *>(malloc(22));
strcpy(blah, " blah blah ");
foo(std::string(blah));
}
- Next message: Bernd Danberg: "main argv command line"
- Previous message: Will Twentyman: "Re: Yet another Attempt at Disproving the Halting Problem"
- In reply to: Tobias Güntner: "Re: strange compiler message"
- Next in thread: Tobias Güntner: "Re: strange compiler message"
- Reply: Tobias Güntner: "Re: strange compiler message"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|