Ошибка, связанная с константой - PullRequest
0 голосов
/ 29 ноября 2010

В 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 ]

2 голосов
/ 29 ноября 2010

Это потому что у вас сломан компилятор.Сломанные компиляторы могут сами выбирать свое поведение.Я знаю, что в некоторых компиляторах эта проблема нарушена.

Посмотрите на MSDN руководство, которое документирует это нарушение поведения.Он прекрасно работает с совместимыми (не нарушенными в этом отношении) компиляторами.

2 голосов
/ 29 ноября 2010

Проблема в том, что при вызове функции вы вызываете foo, но вы определили Foo (с большой буквы F).Оба Foo (re) объявляют одну и ту же функцию, потому что константы верхнего уровня по параметрам не способствуют подписи функции.они игнорируются, если объявление не является определением и если это определение, то переменная параметра считается внутри функции const.Подумайте об этом - если параметр передается как копия (по значению), то для вызывающей стороны абсолютно не имеет значения, будет ли функция изменять копию или нет.Вот почему объявления функций, которые отличаются только верхними уровнями констант по своим параметрам, считаются объявляющими одну и ту же функцию.

0 голосов
/ 29 ноября 2010

Просто чтобы быть абсолютно уверенным, что Армен не сумасшедший:

#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 (обратите внимание на другой случай).

0 голосов
/ 29 ноября 2010

Поскольку вы компилируете в C ++, компилятор рассматривает две функции (одну с const param и одну с неконстантным param) как две отдельные функции (с разным оформленным именем). Только один из них реализован, а другой используется, следовательно, ошибка компоновки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...