Как обойти несоответствие стандартам Visual C ++? - PullRequest
3 голосов
/ 06 января 2011

Согласно этому вопросу , Visual C ++ 2005 (а также 2008/2010) неправильно обнуляет элементы данных.

Поскольку у меня есть код, который требует стандартного поведения и который вылетает в режиме выпуска (а не в отладке), я подозреваю, что проблема возникает здесь.

Теперь проблема в том, что база кода достаточно велика, и проверка классов вручную затруднена.

Есть ли опция компилятора, чтобы вызвать предупреждение об этом нестандартном поведении MSVC? С / W4 вы получаете предупреждения о некоторых нестандартных расширениях (преобразованиях из rvalues ​​в ссылки, пропущенном ключевом слове typename), но не для этой конкретной проблемы.

РЕДАКТИРОВАТЬ: я подозреваю, что подобный код вызывает проблемы (вставлено из связанного вопроса)

include <cassert>

struct B { ~B(); Foo* m; };

int main()
{
   B * b= new B();
   assert ( b->m ==0);
}

в других частях кода у меня есть такие вещи, как

B* b = new B();

, а затем, позже,

if (b->m) { b->m->bar(); }

и b->m должны быть равны нулю по стандарту, но, скорее всего, нет (за исключением режима отладки). Я хотел бы обнаружить такой код (например, предупреждение «m используется без инициализации» или что-то в этом роде)

Ответы [ 4 ]

2 голосов
/ 06 января 2011

Это примерно foo::foo () : member () { }?Вставьте пример (код) проблемы, которую вы видите.В стандартной реализации C ++ член должен иметь значение 0 (при условии, что он имеет фундаментальный тип).Однако некоторые старые компиляторы не делают / реализуют это правильно и просто оставляют его неинициализированным.AFAIK нет предупреждения для этого.Вам нужно будет пройти через код и явно инициализировать член 0 или другим значением.

1 голос
/ 06 января 2011

Не обходите его, атакуйте его напрямую.

Вам понадобится парсер C ++.Используя синтаксический анализатор, вы должны отслеживать типы переменных, которые не были правильно назначены в каждом конструкторе классов.Как только вы это сделаете, просто вставьте правильный синтаксис, чтобы инициализация произошла желаемым образом.Это не простой сценарий для написания, но он избавит вас от головной боли позже.

Первый шаг - это просто получить вывод из дерева разбора, чтобы обозначить проблемы для вас:

class Foo{
public:

    Foo(int a) : mA(a){}

private:

    int mA, mB;
};

васВы захотите, чтобы ваш скрипт генерировал такие сообщения, как: In class Foo :: missing initializer mB

Затем наберитесь храбрости и преобразуйте этот вывод в набор инструкций для обхода дерева разбора и вставки недостающих элементов, чтобы ваш код выглядел так:*

Так что мой лучший совет - не пытаться обойти проблему, атаковать ее напрямую.Если после этого у вас все еще есть проблемы, возьмите ближайший статический анализатор кода и анализатор памяти.Это инструменты, которые помогут вам лучше всего.

1 голос
/ 06 января 2011

Комментарий asper charles ниже, компилятор должен иметь нулевое значение init до вызова ctor.

8.5 An object whose initializer is an empty set of parentheses, i.e., (), shall be
value-initialized. ... Value-initialization for such a class object may be implemented 
by zero-initializing the object and then calling the default constructor

12.1/7 A non-user-provided default constructor for a class ... performs the set of  
initializations of the class that would be performed by a user-written default 
constructor for that class with no ctor-initializer (12.6.2) and an empty
compound-statement.

12.6/4  If a given non-static data member or base class is not named by ... in 
initialiser   list ... the entity is not initialized. 

однако, помните эффективный C ++, если вы объявляете dtor, то вы также должны объявлять копию ctor, ctor и самостоятельное назначение (даже если вы объявляете как private)

0 голосов
/ 06 января 2011

Вы уверены, что вы (люди, якобы цитирующие стандарт ISO C ++) действительно цитируете его?И не путать с текстом для обновленных версий, указанных в ТР, которые на самом деле не являются стандартами?Или C ++ 11, который, вероятно, будет в ближайшее время, но вряд ли можно ожидать, что MS будет соответствовать чему-то, что еще официально не является стандартом.

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