Passing string( "foo" ) to string&.

Started by
6 comments, last by Kiput 18 years, 10 months ago
Hi. Consider following code:
#include <string>
#include <cstdio>

using namespace std;

void foontf( string& str )
{
    printf( str.c_str( ) );
}

int main( )
{
    foontf( string( "foo\n" ) );

    return 0;
}
Compiles fine (and works) on MSVC7, but not on g++ (gcc 3.3.1).
c:\Cplusplus\foo>g++ foo.cpp
foo.cpp: In function `int main()':
foo.cpp:13: error: could not convert `string("foo\n", (&allocator<char>()))' to

   `std::string&'
foo.cpp:7: error: in passing argument 1 of `void foontf(std::string&)'
What's wrong with that code? Is one of the STL implementations buggy? Thanks.
Advertisement
string( "foo\n" ) creates a temporary object. Temporary objects are always const. This means that you would have to pass it as a const string&, not just a string&.
Consider the following code:
void foontf( string* str ){  printf( str->c_str( ) );}int main( ){    foontf( &(string("foo\n")) );    return 0;}

It's <<basically>> the same as the one you posted.
Referencing a temporary value is not something you should normally do.

gcc is known to be much more strict than Visual. Thant's why it declined your request for implicit cast:
string -> string&.

( I'm right, am I? )
Quote:Original post by deffer
Consider the following code:
*** Source Snippet Removed ***
( I'm right, am I? )


Well, right in that it looks like that should compile.

Referencing a temporary variable with a reference is just as safe as referecing a temporary variable with a pointer, however. The temporary isn't destroyed until the statement completes, by which point your function is no longer being called and your references, via reference or pointer, are gone. You may be thinking of returning LOCAL variables by reference, which is bad, because the local variable will be destroyed when the function ends - as you're returning - leaving you having returned a reference to an allready destroyed object.

Dranith hit the nail on the head when he said the function should take a const reference, and I'd agree with you on compiler strictness (GCC vs VS) although I don't really know this for a fact myself :-).
I wouldn't say gcc is stricter... Just different. You can do this in gcc and not msvc:

int a = 100;
char c[a];


Not so strict is it?
Variable length arrays are a language extension. Compile with -pedantic and it will reject it.

x:x: error: ISO C++ forbids variable-size array `c'
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Quote:Original post by chad_420
I wouldn't say gcc is stricter...


It's not about what it implements, it's about following the standards blindly.
Example?

I had some code full of templates with internal typedefs written in MSVC. As sometimes it is required to use "typename" keyword, and I didn't knew exactly when or why (I do now), I ended up typing it everywhere, like:
typedef typename TemplatedClass<TParam> CClassName;

When I was porting it to gcc, I found out I'm only allowed to use the keyword where it <has to> be used. And that was not helpful at all.
Anyway, in the end I just had to learn whens and whys of typename, which turned out for the best for me.

So I'm not saying MSVC does better job, it just does better semantics ;)
Ok, thanks for replys. =)

This topic is closed to new replies.

Advertisement