Прощаи робот-да здравствует маразм - страница 7

 
Renat:
 ...

Тестирование этого примера:

  • MQL4/MQL5 - дает предупреждения о потенциальной ошибке

  • Visual Studio 2012, включая Code Analysis - ничего, качество анализа на потенциальные ошибки вообще на нуле. Они не парятся, так как конкурентов давно уже нет.

  • PVS Studio - сообщает верно

  • Lint - выдает аналогично, declaration 'x' hide...

    ...

Pavlick:

Я тоже думаю, что сообщения совершенно бесполезные. Я не проф программист, но меня такая ерунда в мкл напрягает. Интересно, если ссылки на a и b будут константными, PVS Studio выдаст предупреждение (нет возможности проверить самому)?

Все же не плохо вначале разобраться в сути предупреждения, а потом приводить в качестве аргумента. PVS Studio ругается не из-за скрытия глобальной переменной, а из-за того, что a и b переданы по неконстантной ссылке, но не модифицируются. В таком случае, по их мнению, a и b должны быть переданы по константной сслке. Например, следующие примеры не вызывают у этого анализатора претензий:

int a=1,b=2;
int sum(const int& a, const int& b){
        return(a+b);
}

int main(){
        return sum(a,b);
}

//-------------------------------------------------
int a=1,b=2;
int sum(int& a, int& b){
        ++a; ++b;
        return(a+b);
}

int main(){
        return sum(a,b);
}
 

Я отлично знаю на что ругается PVS.

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

Дай бог несколько процентов авторов MQL4/5 кода являются профессиональными(в настоящем понимании) программистами. Все остальные лишь самоучки и даже понятия не имеют, насколько плохо пишут код.

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

Поэтому надо не предъявлять претензии о выдаче предупреждений, а исправлять свой код.

 
Renat:

Я отлично знаю на что ругается PVS.

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

Дай бог несколько процентов авторов MQL4/5 кода являются профессиональными(в настоящем понимании) программистами. Все остальные лишь самоучки и даже понятия не имеют, насколько плохо пишут код.

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

Поэтому надо не предъявлять претензии о выдаче предупреждений, а исправлять свой код.


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

Можно было бы не перекапывать этот код, половина не исправлена, а поломана. Можно было просто сделать дополнительное свойство, чтобы различать старый mql4, новый или новый со strict. Какой размер занимает старый компилятор? Незнаю, но наверно меньше мегабайта, никаких проблем таскать его с собой в эпоху гигабайтов. Но вот такой вот типа геройский труд выполнен - по уничтожению codebase.

* * *

Предупреждение

declaration of 'a' hides global declaration at line X

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

 
Integer:


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

Можно было бы не перекапывать этот код, половина не исправлена, а поломана. Можно было просто сделать дополнительное свойство, чтобы различать старый mql4, новый или новый со strict. Какой размер занимает старый компилятор? Незнаю, но наверно меньше мегабайта, никаких проблем таскать его с собой в эпоху гигабайтов. Но вот такой вот типа геройский труд выполнен - по уничтожению codebase.

Именно исправлена, а не поломана.

Если после правок проскочила ошибка, то это вполне возможно - любое редактирование неминуемо приводит к таким ошибкам. Но это не означает, что на флаг можно вешать единичные ошибки и лезть на гору исправленных.


declaration of 'a' hides global declaration at line X

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

Удивительные люди, борящиеся за право самострела. Особенно радует, что человек на полном серьезе пишет "оставьте старый компилятор".
 
simpleton:

Потенциальная ошибка на то и потенциальная, что это - совсем не обязательно ошибка.

Ну хз хз. У нас раньше правило было на релиз выставлять 4 или 5 уровень варнингов и галочку считать варнинги ошибками.

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

 
Andrei01:

Данная ремарка бессмысленна и никакой полезной информации программисту не несет в принципе, так как  никакого сокрытия переменной "а" тут нет изначально, как утверждается.

1.cpp(3): remark #3280: declaration hides variable "a" (declared at line 1)
  int sum(int& a, int& b){        

Если программист сознательно использует сокрытие, то - да, данная ремарка бессмысленна и не несёт полезной информации. Если же сокрытие произошло случайно, по невнимательности, то данная ремарка позволяет обнаружить ошибку на ранней стадии.

Andrei01:

Сокрытие возникает лишь когда создается локальная копия переменной, что тоже совершенно законное действие. Даже если возникнет вдруг из-за этого сокрытия ошибка в коде, то она легко находится именно потому что поиск сразу находит одинаковые имена. Если же начать менять и коверкать имена в шаблоне функции, а именно это является "решением" данной ремарки по логике компилятора, то ситуация с поиском ошибок станет гораздо сложней да и путаницы прибавится немеряно в понимании кода. Вроде же очевидно.

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

Сокрытие никак не связано с копиями переменных, оно связано с именами сущностей. Да, хоть, с именами таких сущностей, как типы:

class A { };

void f(int a) {
        A x;
}

это компилируется:

$ icpc -c 1.cpp
$ 

А это:

class A { };

void f(int A) {
        A x;
}

уже - нет:

$ icpc -c 1.cpp
1.cpp(4): error: expected a ";"
        A x;
          ^

compilation aborted for 1.cpp (code 2)
$ 

Потому что имя A внутри функции - это уже не имя типа, а имя переменной-параметра. Имя типа, объявленной во внешней области видимости, теперь скрыто именем переменной-параметра. В этом можно косвенно убедиться, обнаружив что данный код:

class A { };

void f(int A) {
        A++;
}

вполне успешно компилируется:

$ icpc -c 1.cpp
$ 

В MQL4++ такое не компилируется уже на стадии сокрытия имени типа именем переменной-параметра, то есть, даже с пустым телом функции:

#property strict

class A { };
void f(int A) { }
void OnStart() { }

результат:

'A' - structure identifier cannot be used       3.mq4   4       12
'A' - structure identifier cannot be used       3.mq4   4       12

Не знаю, почему, но я нисколько этому не удивлён.

Для C++ же никаких проблем с таким кодом нет:

class A { };
void f(int A) { }

результат попытки компиляции:

$ icpc -c 1.cpp
$ 

Данный пример показывает, что сокрытие связано именно с именами сущностей, а не с чем-то ещё.

Если ремарка - неотключаемая, то - да, приходится изобретать всякие способы, типа коверканья имён. Но, если она - отключаемая, как в компиляторе Intel, то таких проблем нет.

В MQL4++ проблема не с самой функциональностью компилятора по детектированию сокрытия имён во вложенных областях видимости, а именно с принципиальной неотключаемостью этой функциональности.

 
Renat:

Поэтому надо не предъявлять претензии о выдаче предупреждений, а исправлять свой код.

Претензия по обсуждаемым предупреждениям/ремаркам, думаю, может быть одна - об их принципиальной неотключаемости.

И, естественно, нельзя указывать программисту, что ему делать в пределах языка, а что - нет.

 

Подобные сообщения (скрытия глобальных переменных) в C++ просто бессмысленны (mql декларировался ведь как с++ подобный, верно?). Например, вот почему:

struct S1{
    int val;
};

struct S2{};

template<typename _T>
struct SS : _T{
    int f() {int val; return val;}
};

int main(){
    SS<S1> q1; q1.f();
    SS<S2> q2; q2.f();
}
 
Pavlick:

Подобные сообщения (скрытия глобальных переменных) в C++ просто бессмысленны (mql декларировался ведь как с++ подобный, верно?). Например, вот почему:

struct S1{
    int val;
};

struct S2{};

template<typename _T>
struct SS : _T{
    int f() {int val; return val;}
};

int main(){
    SS<S1> q1; q1.f();
    SS<S2> q2; q2.f();
}

C++ здесь был взят потому, что в MQL4++ нет шаблонов структур/классов, - только шаблоны функций?

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

#property strict

struct S1 { };
struct S2 { int val; };

template <typename T>
void f(T &t) {
  struct SS: public T {
    int f(int val) { return val; }
  } ss = {0}; // Переменная типа SS
}

void OnStart() {
  S1 s1; f(s1);
  S2 s2; f(s2);
}

при компиляции выскакивает одно-единственное предупреждение о сокрытии имени:

'3.mq4' 3.mq4   1       1
struct has no members, size assigned to 1 byte  3.mq4   3       8
struct has no members, size assigned to 1 byte  3.mq4   8       10
declaration of 'val' hides member declaration at line 4 3.mq4   9       15
0 error(s), 3 warning(s)                1       4

Если же закомментировать последнюю значащую строчку в OnStart(), предупреждение о сокрытии имени исчезает.

 
simpleton:

C++ здесь был взят потому, что в MQL4++ нет шаблонов структур/классов, - только шаблоны функций?

...

В целом да, но можно и на мкл:

struct S1{
    int val;
};

struct S2{};

#define INSTANTIATE(_Name, _T)          \
    struct _Name : _T                   \
    {                                   \
        int f() {int val; return val;}; \
    }

INSTANTIATE(SS1, S1);
INSTANTIATE(SS2, S2);

void start(){
    SS1 q1; q1.f();
    SS2 q2; q2.f();
}
Причина обращения: