为什么编译器不能正确检测错误的函数签名? [英] Why the Compiler does not detect correct function signature in error?

查看:136
本文介绍了为什么编译器不能正确检测错误的函数签名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题在于提及 ,这是早些时候发布。

虽然OP很高兴接受解决他的问题的答案,我有一个有趣的细节,为什么编译器给出一个看似错误的错误。



下面是我创建的一个小代码示例,演示如下:

  class YourClass 
{
};

class YourClass2
{
};
class MyClass
{
public:
void doSomething(YourClass2 obj)
{
//没有更多有趣的事
}

};

int main()
{
YourClass * ptr = new YourClass();
MyClass obj;
obj.doSomething(ptr);

return 0;
}

编译 使用 GCC(4.3.4)显示一个看似奇怪的错误结果:

  prog.cpp:在函数'int main()':
prog.cpp:23:error:没有匹配函数调用'MyClass :: doSomething(YourClass *&)'
prog.cpp:13:note:candidate are:void MyClass :: doSomething(YourClass2)






因此问题是:

为什么编译器处理调用, p>

  obj.doSomething(ptr); 

作为对原型函数的调用,

  MyClass :: doSomething(YourClass *&)

而不是

  MyClass :: doSomething(YourClass *)
解决方案

正如其他人所说的那样,p>

,编译器试图有帮助,可能会让你困惑。让我们从最简单的错误开始:


错误:没有匹配的函数调用 obj.doSomething / code>


错误消息正确,提供的信息非常有限。在这个例子中代码很简单,但是考虑一个更复杂的代码段。您读取错误讯息,您可能会认为... 什么是obj?,什么是ptr?所以它试图帮助你,告诉你什么 obj is:


错误:没有匹配的函数调用'MyClass :: doSomething(ptr)'


好了,更好的是,它告诉你至少在什么类,你需要寻找超载,但认为该类 std: :ostream 和函数运算符<< ...只有太多的重载,还有什么类型 ptr ?所以它向前移动并尝试描述参数:参数是类型 YourClass * ...的一个 ...我已经看到类型错误消息:


错误:没有匹配的函数调用'MyClass :: doSomething',需要 YourClass * lvalue作为参数。


好,错误报告完成。现在认为函数可能有更多的参数,并且错误消息可以变成一个复杂的野兽(想象一下列表5类型XXX的右值和类型YYY和...的左值)。接下来的事情是使错误消息的语法是精确的(参数的 lvalue 性很重要,或者 rvalue 信息必须存在)。因此它会再次重写错误消息:


错误:没有匹配函数调用'MyClass :: doSomething(YourClass *&


问题是你试图将它解释为函数签名,但它是函数调用的描述。



错误消息未在标准中定义,它们因编译器而异,即使在同一编译器中从一个版本到另一个。在一天结束时,您需要学习阅读错误消息及其含义。


The question is in reference to this, which was posted a little while earlier.
While the OP was happy accepting the answer which solved his problem I was a little intrigued with a detail as to why compiler gave a seemingly wrong error.

Below is a small code sample I created to demonstrate the same:

    class YourClass
    {
    };

    class YourClass2
    {
    };
    class MyClass
    {
        public:
            void doSomething(YourClass2 obj)
            {
                //Nothing more Interesting to do
            }

    };

    int main()
    {
        YourClass *ptr = new YourClass();
        MyClass obj;
        obj.doSomething(ptr);

        return 0;
    }

Compiling this with GCC(4.3.4) gives a seemingly strange error result:

prog.cpp: In function ‘int main()’:
prog.cpp:23: error: no matching function for call to ‘MyClass::doSomething(YourClass*&)’
prog.cpp:13: note: candidates are: void MyClass::doSomething(YourClass2)


So the Question is:
Why does the compiler treat the call,

obj.doSomething(ptr);

as call to a function with prototype,

MyClass::doSomething(YourClass*&)

and not

MyClass::doSomething(YourClass*)

which seems to be the obvious case.

解决方案

As others have stated, the compiler is trying to be helpful, and probably confusing you. Lets start with the simplest error:

error: no matching function for call to obj.doSomething(ptr)

While the error message is correct, the information that it provides is very limited. In this example the code is simple to follow, but consider a more complex piece of code. You read the error message and you may think... what's obj?, what's ptr? So it tries to help you and tells you what obj is:

error: no matching function for call to ‘MyClass::doSomething(ptr)’

Well, that's better, it is telling you at least in what class you need to look for the overload, but consider that the class was std::ostream and the function operator<<... there are just too many overloads, and still, what is the type of ptr? So it moves forward and tries to describe the argument: The argument is an lvalue of type YourClass*... and I have seen that type of error message produced in the past:

error: no matching function for call to ‘MyClass::doSomething’ that takes an YourClass* lvalue as argument.

Ok, so the error report is complete. Now think that the function might have more arguments, and the error message can turn into a complex beast (imagine a list of 5 "rvalue of type XXX and an lvalue of type YYY and ..."). The next thing is making the syntax of the error message just as precise (the lvalue-ness of the argument is important, or the rvalue-ness would be important, so that piece of information has to be present). So it rewrites the error message again:

error: no matching function for call to ‘MyClass::doSomething(YourClass*&)’

The problem is that you are trying to interpret that as a function signature, but it is rather the description of the function call.

Error messages are not defined in the standard, and they differ from one compiler to another, even from one version to another within the same compiler. At the end of the day you need to learn to read the error messages and what they mean.

这篇关于为什么编译器不能正确检测错误的函数签名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆