Недавно наткнулся в MS Visual Studio 2012 на неприятный баг... Обозначенная в данной теме ошибка компилятора MS Visual Studio 2012 не является смертельной и её можно обойти (ниже способ будет указан), однако она опасна, т.к. наличие оной может неожиданно привести либо к неправильной работе программы (если в глобальном пространстве имён компилятором будет обнаружена другая функция с такой же сигнатурой, пусть даже не вами объявленная), либо, в противном случае, выдаст ошибку времени редактирования связей.
В интернете обнаружил такую заявку, с той же самой проблемой, которая, как оказалось, была найдена ещё в марте 2012-го и указана Майкрософту. Ответ на баг был таким:
>We have confirmed that this is a bug in our compiler and it has been fixed.
т.е. по-русски это так:
> Мы подтвердили, что это является ошибкой нашего компилятора и зафиксировали это.
Смотрим на статус заявки: Closed as Deferred, т.е. Закрыта как Отсроченная. Т.о. получается, что о проблеме знают, но её решение отложено в долгий ящик.
А теперь, подробней о самой проблеме...
Вариант первый:
/*
MS Visual Studio 2012 compiler
bug...
*/
#include <cstdio>
namespace Myspace{
struct Foo{
static void Test(){
void Hi(); // declaration
Hi(); // calling
}
};
static void Test(){
void Hi(); // declaration
Hi(); //
calling
}
}
namespace Myspace{
void Hi(){
printf("Myspace::Hi()\n");
}
}
void Hi(){
printf("::Hi()\n");
}
int main(void){
Myspace::Foo::Test(); // Myspace::Hi()
expected.
Myspace::Test(); // Myspace::Hi() expected.
getchar();
}
/*
Expected
output result:
Myspace::Hi()
Myspace::Hi()
Actual
output result:
::Hi()
::Hi()
*/
Как видим, по факту происходит вызов не той функции, которую мы ожидали. Если объявления пометить как extern, то результат отчасти изменится...
Вариант второй:
/*
MS Visual Studio 2012 compiler
bug...
*/
#include <cstdio>
namespace Myspace{
struct Foo{
static void Test(){
extern void Hi(); // declaration
Hi(); // calling
}
};
static void Test(){
extern void Hi(); // declaration
Hi(); //
calling
}
}
namespace Myspace{
void Hi(){
printf("Myspace::Hi()\n");
}
}
void Hi(){
printf("::Hi()\n");
}
int main(void){
Myspace::Foo::Test(); // Myspace::Hi()
expected.
Myspace::Test(); // Myspace::Hi() expected.
getchar();
}
/*
Expected
output result:
Myspace::Hi()
Myspace::Hi()
Actual
output result:
::Hi()
Myspace::Hi()
*/
Однако, как видим, в первом случае по прежнему происходит вызов функции из глобального пространства имён.
Для того, чтобы код правильно компилировался в MS Visual Studio 2012, объявление функции придётся разместить в её пространстве имён.
/*
MS Visual Studio 2012 compiler
bug...
*/
#include <cstdio>
namespace Myspace{
void Hi(); // declaration
struct Foo{
static void Test(){
Hi(); // calling
}
};
static void Test(){
Hi(); // calling
}
}
namespace Myspace{
void Hi(){
printf("Myspace::Hi()\n");
}
}
void Hi(){
printf("::Hi()\n");
}
int main(void){
Myspace::Foo::Test();
// Myspace::Hi()
expected.
Myspace::Test(); // Myspace::Hi() expected.
getchar();
}
/*
Expected output result:
Myspace::Hi()
Myspace::Hi()
Actual output result:
Myspace::Hi()
Myspace::Hi()
*/
Ещё раз обращаю внимание на то, что указанный баг специфичен для MS Visual Studio 2012 (хотя может и не только для указанной версии).
Комментариев нет:
Отправить комментарий