Connecting Tech Pros Worldwide Forums | Help | Site Map

Why are g++ error messages so daunting?

Markus Dehmann
Guest
 
Posts: n/a
#1: Jul 22 '05
I have started with C++ a few months ago. The language itself is nice,
but what I really don't like are the error messages that I get from
g++.

g++ error messages are often just not helpful.

Sometimes I just take the line number of the error and try to figure
out myself what might be wrong. Or I just remember this error message
and know already: if g++ says error X it really means error Y.

For example, take the following code:

#include <iostream>
class Interface{
public:
virtual std::string &getText() const = 0;
};
class Implementation : public Interface{
std::string text;
public:
Implementation::Implementation(std::string text):text(text){}
std::string &getText() const{
return text;
}
};

bash-2.05b$ g++ -c test.cpp
test.cpp: In member function `virtual std::string&
Implementation::getText()
const':
test.cpp:13: could not convert `this->Implementation::text' to
`std::string&'

The return type of getText() must not be std::string, but const
std::string. But why doesn't g++ just say that? It could say: "Could
not return reference to this->... from a const method"...

For beginners, it's also intimidating to get an error message that
fills several screens from the STL usage
std::vector<std::string> test;
std::cout << test;
The whole "candidates are..." list with 26 entries is anyway
unreadable... There should be a better, more readable way to indicate
an error.

Markus

E. Robert Tisdale
Guest
 
Posts: n/a
#2: Jul 22 '05

re: Why are g++ error messages so daunting?


Markus Dehmann wrote:
[color=blue]
> I have started with C++ a few months ago.
> The language itself is nice, but what I really don't like
> are the error messages that I get from g++.
>
> g++ error messages are often just not helpful.[/color]
[color=blue]
> Sometimes I just take the line number of the error
> and try to figure out myself what might be wrong.
> Or I just remember this error message and know already:
> if g++ says error X it really means error Y.
>
> For example, take the following code:
>
> #include <iostream>
> class Interface {
> public:
> virtual std::string& getText(void) const = 0;
> };[/color]
[color=blue]
> class Implementation: public Interface {[/color]
private:[color=blue]
> std::string text;
> public:
> Implementation(std::string text):text(text) { }[/color]
virtual[color=blue]
> std::string& getText(void) const {
> return text;
> }
> };
>
> bash-2.05b$ g++ -c test.cpp
> test.cpp: In member function `virtual std::string&
> Implementation::getText()
> const':
> test.cpp:13: could not convert `this->Implementation::text' \
> to `std::string&'
>
> The return type of getText() must not be std::string but
> const std::string. But why doesn't g++ just say that? It could say:
> "Could not return reference to this->... from a const method"...
>
> For beginners, it's also intimidating to get an error message that
> fills several screens from the STL usage
> std::vector<std::string> test;
> std::cout << test;
> The whole "candidates are..." list with 26 entries is anyway
> unreadable...
> There should be a better, more readable way to indicate an error.[/color]

[color=blue]
> cat test.cpp[/color]
#include <iostream>
class Interface {
public:
virtual
std::string& getText(void) const = 0;
};

class Implementation: public Interface {
private:
std::string text;
public:
Implementation(std::string text): text(text) { }
virtual
std::string &getText(void) const {
return text;
}
};
[color=blue]
> g++ -Wall -ansi -pedantic -c test.cpp[/color]
test.cpp:8: warning: `class Implementation' \
has virtual functions but non-virtual destructor
test.cpp: In member function \
`virtual std::string& Implementation::getText() const':
test.cpp:15: error: invalid initialization of reference \
of type 'std::string&' from expression \
of type 'const std::string'[color=blue]
> g++ --version[/color]
g++ (GCC) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)

Try the gnu.g++.help newsgroup.
Also, try comparing the GNU C++ diagnostic messages
with the diagnostic messages produced by other compilers.
I think that you will find that they compare favorably.
Don't expect too much from compiler diagnostics.
The compiler can't know what you *intended* to write.
It doesn't pick up "understanding" from comments
or your choice to type and variable names.
Diagnostics are pretty much constrained to the rules
of the C++ computer programming language
which, unfortunately, don't always help you understand
what you did wrong.
JKop
Guest
 
Posts: n/a
#3: Jul 22 '05

re: Why are g++ error messages so daunting?


I tried fiddling with the code. Here's what I've got:

class Interface
{
public:
virtual std::string& GetText() const = 0;
};

class Implementation : public Interface
{
private:

std::string text;

public:

Implementation(const std::string& in_text) : text(in_text) { ; }

virtual std::string& GetText() const
{
return text;
}
};

int main()
{
std::string k = "PooPoo";

Implementation p(k);
}



I'm at a loss to explain why it won't compile. G++ is giving me the
following:


t:/poo.cpp: In member function `virtual std::string& Implementation::GetText
()
const':
t:/poo.cpp:22: could not convert `this->Implementation::text' to
`std::string&'



Anyone?



-JKop
Xenos
Guest
 
Posts: n/a
#4: Jul 22 '05

re: Why are g++ error messages so daunting?



"JKop" <NULL@NULL.NULL> wrote in message
news:AxjEc.3472$Z14.4540@news.indigo.ie...[color=blue]
> I tried fiddling with the code. Here's what I've got:
>
> class Interface
> {
> public:
> virtual std::string& GetText() const = 0;
> };
>
> class Implementation : public Interface
> {
> private:
>
> std::string text;
>
> public:
>
> Implementation(const std::string& in_text) : text(in_text) { ; }
>
> virtual std::string& GetText() const
> {
> return text;
> }
> };
>
> int main()
> {
> std::string k = "PooPoo";
>
> Implementation p(k);
> }
>
>
>
> I'm at a loss to explain why it won't compile. G++ is giving me the
> following:
>
>
> t:/poo.cpp: In member function `virtual std::string&[/color]
Implementation::GetText[color=blue]
> ()
> const':
> t:/poo.cpp:22: could not convert `this->Implementation::text' to
> `std::string&'
>
>
>
> Anyone?[/color]
You are trying to make a constant member function return a non-constant
reference to a member. The compiler is telling you it cannot convert a
const string& to a string&

DrX


JKop
Guest
 
Posts: n/a
#5: Jul 22 '05

re: Why are g++ error messages so daunting?



Thanks.


The following compiles:


#include <string>
#include <iostream>

class Interface
{
public:
virtual std::string& GetText() = 0;
};

class Implementation : public Interface
{
private:

std::string text;

public:

Implementation(const std::string& in_text) : text(in_text) { ; }

virtual std::string& GetText()
{
return text;
}
};

int main()
{
std::string k = "PooPoo";

Implementation p(k);
}



-JKop
Xenos
Guest
 
Posts: n/a
#6: Jul 22 '05

re: Why are g++ error messages so daunting?



"JKop" <NULL@NULL.NULL> wrote in message
news:75kEc.3475$Z14.4355@news.indigo.ie...[color=blue]
>
> Thanks.
>
>
> The following compiles:
>
>
> #include <string>
> #include <iostream>
>
> class Interface
> {
> public:
> virtual std::string& GetText() = 0;
> };
>
> class Implementation : public Interface
> {
> private:
>
> std::string text;
>
> public:
>
> Implementation(const std::string& in_text) : text(in_text) { ; }
>
> virtual std::string& GetText()
> {
> return text;
> }
> };
>
> int main()
> {
> std::string k = "PooPoo";
>
> Implementation p(k);
> }
>
>
>
> -JKop[/color]

Instead of giving the caller write access to the string, I would suggest
"going the way" to fix it. Meaning, keep the member function constant, and
change the return type to const std::string&



JKop
Guest
 
Posts: n/a
#7: Jul 22 '05

re: Why are g++ error messages so daunting?


Xenos posted:
[color=blue]
> Instead of giving the caller write access to the string, I would
> suggest "going the way" to fix it. Meaning, keep the member function
> constant, and change the return type to const std::string&[/color]


I was just trying to get the code to compile without interferring. Good
points though. But then some may say that you should use an accessor
function and return by value... which is a good point also.

-JKop
Ronald Landheer-Cieslak
Guest
 
Posts: n/a
#8: Jul 22 '05

re: Why are g++ error messages so daunting?


JKop wrote:[color=blue]
> Xenos posted:
>
>[color=green]
>>Instead of giving the caller write access to the string, I would
>>suggest "going the way" to fix it. Meaning, keep the member function
>>constant, and change the return type to const std::string&[/color]
>
>
>
> I was just trying to get the code to compile without interferring. Good
> points though. But then some may say that you should use an accessor
> function and return by value... which is a good point also.
>
> -JKop[/color]
returning by value implies a copy (which the compiler may then optimize
away) whereas returning a const reference doesn't (so there's less to do
for the optimizer). Hence

const std::string & MyClass::GetText(void) const;

is preferable to

std::string MyClass::GetText(void) const;

because it doesn't rely on the compiler to optimize the extra copy away.

Note, however, that it does rely on the type of text in the class not
changing: passing back a value is better if you think the type of your
text member variable may change from std::string to something else..

HTH

rlc
JKop
Guest
 
Posts: n/a
#9: Jul 22 '05

re: Why are g++ error messages so daunting?


Ronald Landheer-Cieslak posted:
[color=blue]
> JKop wrote:[color=green]
>> Xenos posted:
>>
>>[color=darkred]
>>>Instead of giving the caller write access to the string, I would
>>>suggest "going the way" to fix it. Meaning, keep the member function
>>>constant, and change the return type to const std::string&[/color]
>>
>>
>>
>> I was just trying to get the code to compile without interferring. Good
>> points though. But then some may say that you should use an accessor
>> function and return by value... which is a good point also.
>>
>> -JKop[/color]
> returning by value implies a copy (which the compiler may then optimize
> away) whereas returning a const reference doesn't (so there's less to do
> for the optimizer). Hence
>
> const std::string & MyClass::GetText(void) const;
>
> is preferable to
>
> std::string MyClass::GetText(void) const;
>
> because it doesn't rely on the compiler to optimize the extra copy away.
>
> Note, however, that it does rely on the type of text in the class not
> changing: passing back a value is better if you think the type of your
> text member variable may change from std::string to something else..
>
> HTH
>
> rlc
>[/color]

But then Implementation must store the string in a fully-fledged string
object. Consider if it pulled if from the air, from the Windows registry,
from the DOS autoexec.bat, then it wouldn't have a reference to return.

-JKop
Markus Dehmann
Guest
 
Posts: n/a
#10: Jul 22 '05

re: Why are g++ error messages so daunting?


JKop <NULL@NULL.NULL> wrote in message news:<AxjEc.3472$Z14.4540@news.indigo.ie>...[color=blue]
> I tried fiddling with the code. Here's what I've got:
>
> class Interface
> {
> public:
> virtual std::string& GetText() const = 0;
> };
>
> class Implementation : public Interface
> {
> private:
>
> std::string text;
>
> public:
>
> Implementation(const std::string& in_text) : text(in_text) { ; }
>
> virtual std::string& GetText() const
> {
> return text;
> }
> };[/color]

I'm curious: Why did you (and E. Robert Tisdale) change my
std::string &getText() const{return text;}
to
virtual std::string &getText() const{return text;}

Is it a convention that in subclasses, the "virtual" keyword should
remain, like in the superclass definition?

Thanks
Markus
JKop
Guest
 
Posts: n/a
#11: Jul 22 '05

re: Why are g++ error messages so daunting?


Markus Dehmann posted:
[color=blue]
> I'm curious: Why did you (and E. Robert Tisdale) change my
> std::string &getText() const{return text;}
> to
> virtual std::string &getText() const{return text;}
>
> Is it a convention that in subclasses, the "virtual" keyword should
> remain, like in the superclass definition?
>
> Thanks
> Markus[/color]


Here's how it starts:

class Interface;

And then:

class Implementation : public Interface;


As the overidden function is virtual in the base class, it's virtual in the
derived class. Even though you haven't written "virtual" in the derived
class, it *has* to be virtual. So there's reason 1:

Reason 1: Because it actually is virtual

Then there's the fact that you can just read through the derived class's
definition and see which functions are virtual, rather than having to check
back with the base class's definition.

Reason 2: It's a convenient indicator in the definition of the derived class
of which functions are in fact virtual, without having to look back at the
definition of the base class.

Now, obviously when you're writing your derived class, you're going to be
aware that this certain function is virtual, and so you going to write code
accordingly. If you derive a class from this derived class, eg.

class SuperImplementation : public Implementation

Then again, this certain function is going to be virtual in
SuperImplementation aswell, and the code will be again be written
accordingly.
Now consider that you change things so that Implementation no longer
inherits from Interface. You haven't specified "virtual" in Implementation,
so this function will no longer be virtual, and concordantly, the function
in SuperImplementation will no longer be virtual either, even though you've
written code according to it being virtual. When this happens, you're going
to have to go back to the derived class and stick in "virtual" to set it
that it's still virtual. You may aswell just stick in in the first place to
avoid this.

Reason 3: When you change the inheritence, the derived class's functions are
still virtual.


-JKop
Ronald Landheer-Cieslak
Guest
 
Posts: n/a
#12: Jul 22 '05

re: Why are g++ error messages so daunting?


JKop wrote:[color=blue]
> Ronald Landheer-Cieslak posted:
>
>[color=green]
>>JKop wrote:
>>[color=darkred]
>>>Xenos posted:
>>>
>>>
>>>
>>>>Instead of giving the caller write access to the string, I would
>>>>suggest "going the way" to fix it. Meaning, keep the member function
>>>>constant, and change the return type to const std::string&
>>>
>>>
>>>
>>>I was just trying to get the code to compile without interferring. Good
>>>points though. But then some may say that you should use an accessor
>>>function and return by value... which is a good point also.
>>>
>>>-JKop[/color]
>>
>>returning by value implies a copy (which the compiler may then optimize
>>away) whereas returning a const reference doesn't (so there's less to do
>>for the optimizer). Hence
>>
>>const std::string & MyClass::GetText(void) const;
>>
>>is preferable to
>>
>>std::string MyClass::GetText(void) const;
>>
>>because it doesn't rely on the compiler to optimize the extra copy away.
>>
>>Note, however, that it does rely on the type of text in the class not
>>changing: passing back a value is better if you think the type of your
>>text member variable may change from std::string to something else..
>>
>>HTH
>>
>>rlc
>>[/color]
>
>
> But then Implementation must store the string in a fully-fledged string
> object. Consider if it pulled if from the air, from the Windows registry,
> from the DOS autoexec.bat, then it wouldn't have a reference to return.[/color]
Did you read the last paragraph of what I wrote?
And the original post? (especially, the class' definition)

Just in case, the OP class definition:
<snip>
#include <iostream>
class Interface{
public:
virtual std::string &getText() const = 0;
};
class Implementation : public Interface{
std::string text;
public:
Implementation::Implementation(std::string text):text(text){}
std::string &getText() const{
return text;
}
};
</snip>

and the last paragraph, with a bit of highlighting:[color=blue][color=green]
>>Note, however, that it does rely on the type of text in the class not[/color][/color]
^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^[color=blue][color=green]
>>changing: passing back a value is better if you think the type of your[/color][/color]
^^^^^^^^[color=blue][color=green]
>>text member variable may change from std::string to something else..[/color][/color]
^^^^^^^^^^^^^^^^^^^^^^^^^^^

So yes, my suggestion does depend on that, as I already pointed out..
Thanks for noticing ;)

rlc
Closed Thread