Почему отладчик Visual Studio 2010 не видит статические члены класса const?

Этот вопрос тесно связан с впоследствии заданным вопросом Вот.

Описан метод определения констант в классе. Вот по Страуструпу.

Когда я следую методу Страуструпа, я вижу ожидаемые результаты. Однако в Visual Studio 2010 отладчик не может разрешить static const член класса в рамках этого класса.
Вот что я имею в виду:

#include <iostream>

class Foo {
public:
static const int A = 50;
char arr[A];
void showA();
};

void Foo::showA() {
std::cout << "showA = " << A << "\n";
}

int main() {
Foo f;
f.showA();
}

Когда отладчик находится в showA (), окно «watch» сообщает:

Error: Symbol "Foo::A" not found

Я хотел бы подчеркнуть, что программа ведет себя так, как и ожидалось, то есть вывод:

showA = 50

и программа возвращает 0.

Кто-нибудь еще может воспроизвести это с Visual Studio 2010? Это ошибка в отладчике?

8

Решение

Visual C ++ ошибочно предоставляет слабое определение (доказательства, представленные в этом ответе) основываясь на объявлении внутри класса, несмотря на ясную формулировку в Стандарте:

Объявление статического члена данных в его определении класса не является определением и может быть неполного типа, кроме cv-квалифицированного void, Определение для статического члена данных должно появиться в области пространства имен, включающей определение класса члена. В определении в области пространства имен имя члена статических данных должно быть квалифицировано по имени его класса с использованием :: оператор.

Согласно другому правилу в Стандарте, определение не требуется, если член не УСО используемый.

Независимо от того, существует ли в Visual C ++ явное или слабое определение, ошибочно предоставленное, разница не имеет. Если участник не УСО используемый, компоновщик не увидит никаких ссылок на него и удалит его, в результате чего отладчик не сможет понять, существовал ли он когда-либо. С помощью компоновщика Microsoft вы можете запретить эту оптимизацию, используя /OPT:NOREF,

В конечном счете, это не то, что вы хотите делать в рабочем коде, поскольку в вашей прикладной программе останутся все виды рудиментарных вещей из стандартной библиотеки. Но для временного использования во время отладки это разумная настройка.

2

Другие решения

Вы можете добавить определение для вашего статического члена данных в глобальной области пространства имен:

const int Foo::A;

Добавление определения члена статических данных, которое не обязательно, но разрешено, похоже, решит вашу проблему.

Я проверил это на отладочной сборке с VS2010, и значение A правильно отображается в окне отладки, когда определение присутствует (в то время как сообщение об ошибке сообщается, когда определение отсутствует, в соответствии с тем, что вы упоминаете).

7

Это не ошибка. Компилятор может (и почти всегда) оптимизирует статические константы базовых типов. Вместо выделения памяти для Aкомпилятор просто указывает на значение A в скомпилированные инструкции.

Так как A нигде не хранится, у него нет адреса, поэтому отладчик не может его просмотреть.

3
По вопросам рекламы [email protected]