与const有关的错误

时间:2010-11-28 21:55:20

标签: c++ compilation const

在Visual Studio 2008中,将成功构建以下代码:

void Foo (int x);//Prototype

void Foo(const int x)//Implementation
{

}

但是,这会在链接期间生成错误(未解析的外部符号):

void Foo (int x);//Prototype

void Foo(const int x)//Implementation
{

}

void Bar()
{
    int x = 0;
    Foo(x);
}

问题是因为Foo的函数实现指定整数参数是常量,而原型不需要常量。

为什么会这样?为什么在编译期间没有检测到问题?

4 个答案:

答案 0 :(得分:2)

问题在于,当您调用该函数时,您调用foo,但您已定义Foo(使用大写字母F)。两个Foo(重新)都声明了相同的函数,因为参数的顶级consts不会影响函数的签名。如果声明不是定义,它们将被忽略,如果它是一个定义,那么参数变量在函数内被认为是const。考虑一下 - 如果参数作为副本(按值)传递,那么调用者是否会更改副本是绝对无关紧要的。这就是为什么函数声明只在顶级参数上有所不同的参数被认为是声明相同的函数。

答案 1 :(得分:2)

这是因为你的编译器坏了。破碎的编译器可以选择自己的行为。我知道有些编译器对这种情况有这种破坏的处理方式。

在MSDN上查看有关记录该行为失败的手册。它适用于兼容(在这方面没有破坏)编译器。

答案 2 :(得分:0)

只是为了确保亚美尼亚不会疯狂:

#include <type_traits>

int main()
{
    static_assert( std::is_same<void(int ), void(const int )>::value, "...");
    static_assert(!std::is_same<void(int&), void(const int&)>::value, "...");
}

这应该适用于任何符合标准的编译器,并且支持最小的C ++ 0x。如果没有,编译器就会崩溃。例如,g ++ 4.5.1接受此代码就好了。

顺便说一句,您的实际问题是您定义了Foo但是调用foo(注意不同的情况)。

答案 3 :(得分:-3)

因为您在C ++中编译,所以编译器将这两个函数(一个使用const param,一个使用非const param)视为两个独立的函数(具有不同的装饰名称)。其中只有一个被实现,另一个被使用,因此链接错误。