On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 28.07.12 18:57. Заголовок: Ответы Microsoft на известные или предполагаемые баги компилятора VC++ 2010


В этой теме можно помещать информацию о известных или предполагаемых вами багах в Visual Studio C++ 2010, на известие о которых поступил ответ от Microsoft.

Одно из таких сообщений, которое я отослал в Microsoft касается следующего, как я считал, бага, и как это подтвердила Microsoft.

Чтобы лучше понимать вопрос, следует сначала обратиться к языку С. В языке С структуры, объединения и перечисления находятся в отдельном пространстве имен от пространства имен других идентификаторов объектов. Это объясняется тем, что перед именем структуры, объекдинения или перечисления в С всегда пишется сначала идентификатор типа, то есть ключевое слово struct, union или enum. Поэтому один и тот же идентификатор можно использовать для обозначения, например, структуры и скалярной переменной, не беспокоясь о коллизии.
Например, в С можно смело писать

struct A 
{
int A;
};


так как если мы хотим использовать структуру, то всегда нужно перед идентификатором ставить ключевое слово struct. например,

void f(); 
{
struct A a = { 10 };
printf( "%d\n", a.A );
}


Однако в С++ имя структуры само по себе означает тип, а потому при объявлении переменных обычно не пишут ключевое слово struct, а определяют объекты данного типа как

A a1;


Поэтому в С++ может возникнуть коллизия имени структуры и такого же имени объекта. В стандарте С++ четко оговорено, в каком случае имя члены структуры может совпадать или не совпадать с именем самой структуры. Это описано в разделе 9.2 Class members #13 В частности, если класс не имеет явно объявленного конструктора, то не статический член класса, имеющего фундаментальный тип, может иметь имя, совпадающее с именем класса (структуры). То есть следующий код

struct A 
{
int A;
};


является корректным и для С++.

Однако компилятор MS VC++ 2010 не компилирует этот код, выдавая сообщение об ошибке: "error C2380: типы перед "A" (конструктор с возвращаемым типом или недопустимое переопределение текущего имени класса?)"

где-то месяц назад я получил ответ от Microsoft на обнаруженный мною баг. Вот их ответ:


 цитата:
Thank you for reporting this issue. This has been known to be an long-standing non-conformance in the compiler but it's really a corner case: note that it prevents the declaration of a constructor. Due to its nature, we regret that we will not fix this issue in the next release of the compiler.

Tanveer Gani
Visual C++ Team.




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

Тем не менее следует знать, что в этом вопросе компилятор MS VC++ 2010 не соответствует стандарту С++.

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 2 [только новые]





ссылка на сообщение  Отправлено: 28.07.12 18:58. Заголовок: Баг в компиляции for..


Баг в компиляции for-предложения, когда в качестве управляющих переменных используются объекты классов

Пример, воспроизводящий баг.

#include "stdafx.h" 

struct T1
{
T1( int i ): x( i ) {}
~T1() {}
int x;
};

struct T2
{
T2( int i ): x( i ) {}
~T2() {}
operator bool() const { return ( x != 0 ); }
int x;
};

int _tmain(int argc, _TCHAR* argv[])
{
int i = 10;

for ( T1 t1 = i; T2 t2 = i; i-- ) {}

return 0;
}


Это вполне корректный код, который должен успешно компилироваться и выполняться.

Компилятор MS VC++ 2010 генерирует сообщение об ощибке

fatal error C1001: Внутренняя ошибка в файле компилятора.
1> (файл компилятора "f:\dd\vctools\compiler\utc\src\p2\ehexcept.c", строка 971)
1> Чтобы обойти эту неполадку, попытайтесь упростить или изменить программу в строках около указанной позиции.
1> Для получения дополнительных сведений выберите команду "Техническая поддержка"
1> в меню "Справка" Visual C++ или откройте файл справки технической поддержки.


Вот ответ от Майкрософт, где они признают, что это баг, и предлагают способ его обхода посредством замены в управляюшем предложении конструкции T2 t2 = i;. на T2( i );.


 цитата:
Thank you for reporting this issue to Microsoft. We can confirm that it is indeed a bug in the compiler but fortunately the workaround is simple. For the test-clause of the loop, instead of writing T2 t2 = i, just write T2(i), which has similar effect.

Due to the rarity of the construct and the point we are in the Dev11 release cycle, we regret that we cannot fix this bug for Dev11. Please continue to use the workaround and we'll consider it for a future release.

Tanveer Gani
Visual C++ Team



Из ответа следует, что этот баг не будет исправлен в ближайшей версии компилятора, то есть в версии VC++ 2011.
Предложенный Майкрософт способ обхода бага не является полностью удовлетворительным, так как это не эквивалентная по семантике замена исходной конструкции. В первом случае создается объект с именем t2, который может использоваться внутри тела цикла, а во втором случае создается временный объект, который тотчас же удаляется и не доступен внутри тела цикла.
Это было отмечено в оставленном в ответ на их сообщение комментарии:

 цитата:
In general T2(i) has no the similar effect as T2 t2 = i, because in the last case a local variable is defined that can be used inside the loop body.





Спасибо: 0 
ПрофильЦитата Ответить



ссылка на сообщение  Отправлено: 28.07.12 18:59. Заголовок: Баг компилятора MS V..


Баг компилятора MS VC++ 2010 при поиске имен в случае задания дружественной функции.

Примеры , воспроизводящие баг.

#include "stdafx.h"   
#include <iostream>

void f() { std::cout << "::f()\n"; }

namespace N1
{

struct A
{
friend void f();
};

void g() { f(); }

void f() { std::cout << "N1::f()\n"; }

}

int _tmain(int argc, _TCHAR* argv[])
{
N1::g();
}


Ожидаемый результат: вывод текста на консоль

::f()

Полученный результат: вывод текста на консоль

N1::f()

Пример из раздела 3.4.1 "Unqualified name lookup" в параграфе 3 стандарта С++

typedef int f;   
namespace N {
struct A {
friend void f(A &);
operator int();
void g(A a) {
int i = f(a); // f is the typedef, not the friend
// function: equivalent to int(a)
}
};
}


Оэидаемый результат: согласно стандарту в функции g будет вызвана не дружественная функция f, а оператор преобразования типа, так как имя f будет синонимом типа int.

Полученный результат: сообщение об ошибке компилятора "error C2440: инициализация: невозможно преобразовать "void" в "int" Выражение, имеющее тип void, нельзя преобразовать в другой тип"


Согласно станларту С++ 2011 (и 2003) в соответствии с разделом 7.3.1.2 "Namespace member definitions" #3
"...The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3)
until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship)...." То есть имя дружественной функции не будет найдено при поиске квалифицированных или неквалифицированных имен до тех пор, пока в данном пространстве имен не появится соответствующее объявление дружественной функции или класса вне класса, давшего дружбу.

Однако компилятор MS VC++ 2010 находит имя дружественной функции до ее объявления.


Ответы Майкрософт из переписки с ними по этой проблеме


 цитата:
Posted by Microsoft on 1/5/2012 at 2:28 PM

Hi: the compiler is behaving correctly in this case. In section 7.3.1.2/p3 of the C++ Standard it states:

"If a friend declaration in a non-local class first declares a class or function the friend class or function is a member of the innermost enclosing namespace."

Jonathan Caves
Visual C++ Compiler Team




 цитата:
Posted by Сыроежка on 1/6/2012 at 3:45 AM

But further in the same paragraph the following is written "The name of the friend is not found by unqualified lookup (3.4.1) or by qualified lookup (3.4.3) until a matching declaration is provided in that namespace scope (either before or after the class definition granting friendship)." And below this text there is an example in which there is statement
// A::f, A::g and A::h are not visible here.

However due to the example I presented in my feedback the compiler finds the name of the friend before the declaration of the friend in the scope.




 цитата:
Posted by Microsoft on 06.01.2012 at 8:20

Ah yes ... now I see what is going: this is indeed a bug in Visual C++. Unfortunately it is unlikely that we'll be able to fix this for the upcoming release - but we will keep the bug in our database and look at it during the development of a a future release.

Sorry for the confusion and thanks for correcting me.
Jonathan Caves
Visual C++ Compiler Team



Майкрософт признал, что это баг компилятора, однако, как следует из их ответа, вероятно этот баг не будет устранен в следующей реализации компилятора, то есть в MS VC++ 2011.

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 27
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет