Implicit conversion from string to number как исправить

Konstantin Erin:

1. Судя по всему, LabelCreate() – это Ваша пользовательская функция. И что второй параметр? Обратный слеж используется для указания Esc-последовательностей: n – новая строка  (посмотрите ссылку), t – табуляция и т.д. а Вам что нужно?

2. Поставьте курсор на datetime и нажмите F1 – примеры задания времени: datetime A = D’23:59′;

3. Ставьте курсор на OBJPROP_FONT и нажмите F1 -надо ObjectSetString

4. int m=CurTime(); F1 Устарело, надо TimeCurrent() F1. Возвращает datetime 8 байт, как уместить лишь в 4 байта int ? Попробуйте long

ну и так далее …  Почаще нажимайте F1

Спасибо, помогли, не понятно что с 3 пунктом:
вот код:

      if (ObjectCreate(0, "MouseInfo", OBJ_LABEL, 0, 0, 0)) ObjectSetString(0, "MouseInfo", OBJPROP_TEXT, " ");
      ObjectSet("MouseInfo", OBJPROP_BACK, false);                    // Рисовать объект в фоне
      ObjectSet("MouseInfo", OBJPROP_SELECTED, false);                // Снять выделение с объекта
      ObjectSet("MouseInfo", OBJPROP_SELECTABLE, false);              // Запрет на редактирование
      ObjectSet("MouseInfo", OBJPROP_HIDDEN, true);                   // Скроем (true) или отобразим (false) имя графического объекта в списке объектов
      ObjectSet("MouseInfo", OBJPROP_FONT, "Arial");
      ObjectSet("MouseInfo", OBJPROP_FONTSIZE, 10);
      ObjectSet("MouseInfo", OBJPROP_COLOR, clrDodgerBlue);

и первый, мне нужно просто на экране получить OBJ_LABEL, в котором 2 символа:

Введение

При использовании новой версии компилятора языка MQL4 некоторые старые программы могут выдавать ошибки.

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

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

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

  1. Ошибки компиляции
    • 1.1. Идентификатор совпадает с зарезервированным словом
    • 1.2. Специальные символы в наименованиях переменных и функций
    • 1.3. Ошибки использования оператора switch
    • 1.4. Возвращаемые значения у функций
    • 1.5. Массивы в аргументах функций
  2. Ошибки времени выполнения
    • 2.1. Выход за пределы массива (Array out of range)
    • 2.2. Деление на ноль (Zero divide)
    • 2.3. Использование 0 вместо NULL для текущего символа
    • 2.4. Строки в формате Unicodе и их использование в DLL
    • 2.5. Совместное использование файлов
    • 2.6. Особенность преобразования datetime
  3. Предупреждения компилятора
    • 3.1. Пересечения имен глобальных и локальных переменных
    • 3.2. Несоответствие типов
    • 3.3. Неиспользуемые переменные

1. Ошибки компиляции

При наличии ошибок в коде программа не может быть скомпилирована.

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

#property strict

Этот режим значительно упрощает поиск ошибок.

1.1. Идентификатор совпадает с зарезервированным словом

Если наименование переменной или функции совпадает с одним из зарезервированных слов:

int char[];  
int char1[]; 
int char()   
{
 return(0);
}

то компилятор выводит сообщения об ошибках:

Рис.1. Ошибки "unexpected token" и "name expected"

Рис.1. Ошибки “unexpected token” и “name expected”

Для исправления данной ошибки нужно исправить имя переменной или функции.

1.2. Специальные символы в наименованиях переменных и функций

Если наименования переменных или функций содержат специальные символы ($, @, точка):

int $var1; 
int @var2; 
int var.3; 
void f@()  
{
 return;
}

то компилятор выводит сообщения об ошибках:

Рис.2. Ошибки "unknown symbol" и "semicolon expected"

Рис.2. Ошибки “unknown symbol” и “semicolon expected”

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

1.3. Ошибки использования оператора switch

Старая версия компилятора позволяла использовать любые значения в выражениях и константах оператора switch:

void start()
  {
   double n=3.14;
   switch(n)
     {
      case 3.14: Print("Pi");break;
      case 2.7: Print("E");break;
     }
  }

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

Рис.3. Ошибки "illegal switch expression type" и "constant expression is not integral"

Рис.3. Ошибки “illegal switch expression type” и “constant expression is not integral”

В таких случаях можно использовать явные сравнения численных значений, например:

void start()
  {
   double n=3.14;
   if(n==3.14) Print("Pi");
   else
      if(n==2.7) Print("E");
  }

1.4. Возвращаемые значений функций

Все функции, кроме void, должны возвращать значение объявленного типа. Например:

int function()
{
}

При строгом режиме компиляции (strict) возникает ошибка:

Рис.4. Ошибка "not all control paths return a value"

Рис.4. Ошибка “not all control paths return a value”

В режиме компиляции по умолчанию компилятор выводит предупреждение:

Рис.5. Предупреждение "not all control paths return a value"

Рис.5. Предупреждение “not all control paths return a value”

Если возвращаемое значение функции не соответствует объявлению:

int init()                         
  {
   return;                          
  }

то при строгом режиме компиляции возникает ошибка:

Рис.6. Ошибка "function must return a value"

Рис.6. Ошибка “function must return a value”

В режиме компиляции по умолчанию компилятор выводит предупреждение:

Рис.7. Предупреждение 'return - function must return a value"

Рис.7. Предупреждение ‘return – function must return a value”

Для исправления таких ошибок в код функции нужно добавить оператор возврата return c возвращаемым значением соответствующего типа.

1.5. Массивы в аргументах функций

Массивы в аргументах функций теперь передаются только по ссылке.

double ArrayAverage(double a[])
{
 return(0);
}

Данный код при строгом режиме компиляции (strict) приведет к ошибке:

Рис.8. Ошибка компилятора "arrays passed by reference only"

Рис.8. Ошибка компилятора “arrays passed by reference only”

В режиме компиляции по умолчанию компилятор выводит предупреждение:

Рис.9. Предупреждение компилятора "arrays passed by reference only"

Рис.9. Предупреждение компилятора “arrays passed by reference only”

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

double ArrayAverage(double &a[])
{
 return(0);
}

Следует отметить, что теперь константные массивы (Time[], Open[], High[], Low[], Close[], Volume[]) не могут быть переданы по ссылке. Например, вызов:

ArrayAverage(Open);

вне зависимости от режима компиляции приводит к ошибке:

Рис.10. Ошибка 'Open' - constant variable cannot be passed as reference

Рис.10. Ошибка ‘Open’ – constant variable cannot be passed as reference

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

   
   double OpenPrices[];
   
   ArrayCopy(OpenPrices,Open,0,0,WHOLE_ARRAY);
   
   ArrayAverage(OpenPrices);

2. Ошибки времени выполнения

Ошибки, возникающие в процессе исполнения кода программы принято называть ошибками времени выполнения (runtime errors). Такие ошибки обычно зависят от состояния программы и связаны с некорректными значениями переменных.

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

2.1. Выход за пределы массива (Array out of range)

Эта ошибка часто возникает в индикаторах при обращении к индикаторным буферам. Функция IndicatorCounted() возвращает количество баров, неизменившихся после последнего вызова индикатора. Значения индикаторов на уже рассчитанных ранее
барах не нуждаются в пересчете, поэтому для ускорения расчетов
достаточно обрабатывать только несколько последних баров.

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



int start()
  {
   
   if (Bars<100) 
     return(-1); 

   
   int counted_bars=IndicatorCounted();
   
   if(counted_bars<0) return(-1);
      
   
   int limit=Bars-counted_bars;

   
   if(counted_bars==0) 
     {
      limit--;  
      
      limit-=10;
     }
   else 
     {     
      
      limit++;
     } 
   
   for (int i=limit; i>0; i--)
   {
     Buff1[i]=0.5*(Open[i+5]+Close[i+10]) 
   }
}

Часто встречается некорректная обработка случая counted_bars==0 (начальную позицию limit нужно уменьшить на значение, равное 1 + максимальный индекс относительно переменной цикла).

Также следует помнить о том, что в момент исполнения функции start() мы можем обращаться к элементам массивов индикаторных буферов от 0 до Bars()-1. Если есть необходимость работы с массивами, которые не являются индикаторными буферами, то их размер следует увеличить при помощи функции ArrayResize() в соответствии с текущим размером индикаторных буферов. Максимальный индекс элемента для адресации также можно получить вызовом ArraySize() с одним из индикаторных буферов в качестве аргумента.

2.2. Деление на ноль (Zero divide)

Ошибка “Zero divide” возникает в случае, если при выполнении операции деления делитель оказывается равен нулю:

void OnStart()
  {

   int a=0, b=0,c;
   c=a/b;
   Print("c=",c);
  }

При выполнении данного скрипта во вкладке “Эксперты” возникает сообщение об ошибке и завершении работы программы:

Рис.11. Сообщение об ошибке "zero divide"

Рис.11. Сообщение об ошибке “zero divide”

Обычно такая ошибка возникает в случаях, когда значение делителя определяется значениями каких-либо внешних данных. Например, если анализируются параметры торговли, то величина задействованной маржи оказывается равна 0 если нет открытых ордеров. Другой пример: если анализируемые данные считываются из файла, то в случае его отсутствия нельзя гарантировать корректную работу. По этой причине желательно стараться учитывать подобные случаи и корректно их обрабатывать.

Самый простой способ – проверять делитель перед операцией деления и выводить сообщение об некорректном значении параметра:

void OnStart()
  {

   int a=0, b=0,c;
   if(b!=0) {c=a/b; Print(c);}
   else {Print("Error: b=0"); return; };
  }

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

Рис. 12. Сообщение о некорректном значении делителя

Рис. 12. Сообщение о некорректном значении делителя

2.3. Использование 0 вместо NULL для текущего символа

В старой версии компилятора допускалось использование 0 (нуля) в качестве аргумента в функциях, требующих указания финансового инструмента.

Например, значение технического индикатора Moving Average для текущего символа можно было запрашивать следующим образом:

AlligatorJawsBuffer[i]=iMA(0,0,13,8,MODE_SMMA,PRICE_MEDIAN,i); 

В новом компиляторе для указания текущего символа нужно явно указывать NULL:

AlligatorJawsBuffer[i]=iMA(NULL,0,13,8,MODE_SMMA,PRICE_MEDIAN,i); 

Кроме того, текущий символ и период графика можно указать при помощи функций Symbol() и Period().

AlligatorJawsBuffer[i]=iMA(Symbol(),Period(),13,8,MODE_SMMA,PRICE_MEDIAN,i); 

2.4. Строки в формате Unicodе и их использование в DLL

Строки теперь представляют собой последовательность символов Unicode.

Следует учитывать этот факт и использовать соответствующие функции Windows. Например, при использовании функций библиотеки wininet.dll вместо InternetOpenA() и InternetOpenUrlA() следует вызывать InternetOpenW() и InternetOpenUrlW().

В MQL4 изменилась внутренняя структура строк (теперь она занимает 12 байт), поэтому при передаче строк в DLL следует использовать структуру MqlString:

#pragma pack(push,1)
struct MqlString
  {
   int      size;       
   LPWSTR   buffer;     
   int      reserved;   
  };
#pragma pack(pop,1)

2.5. Совместное использование файлов

В новом MQL4 при открытии файлов необходимо явно указывать флаги FILE_SHARE_WRITE и FILE_SHARE_READ для совместного использования.

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

Например, при работе с оффлайновыми графиками требуется явно указывать флаги совместного доступа:

   
   ExtHandle=FileOpenHistory(c_symbol+i_period+".hst",FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ);

Подробности можно найти в статье в статье “Оффлайновые графики и новый MQL4“.

2.6. Особенность преобразования datetime

Следует иметь ввиду, что преобразование типа datetime в строку теперь зависит от режима компиляции:

  datetime date=D'2014.03.05 15:46:58';
  string str="mydate="+date;

Например, попытка работы с файлами, имя которых содержит двоеточие, приведет к ошибке.

3. Предупреждения компилятора

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

Чистый код не должен содержать предупреждений.

3.1. Пересечения имен глобальных и локальных переменных

Если на глобальном и локальном уровнях присутствуют переменные с одинаковыми именами:

int i; 
void OnStart()
  {

   int i=0,j=0; 
   for (i=0; i<5; i++) {j+=i;}
   PrintFormat("i=%d, j=%d",i,j);
  }

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

Рис.13. Предупреждение "declaration of '%' hides global declaration at line %"

Рис.13. Предупреждение “declaration of ‘%’ hides global declaration at line %”

Для исправления таких предупреждений нужно скорректировать имена глобальных переменных.

3.2. Несоответствие типов

В новой версии компилятора введена операция приведения типов.

#property strict
void OnStart()
  {
   double a=7;
   float b=a;
   int c=b;
   string str=c;
   Print(c);
  }

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

Рис.14. Предупреждения "possible loss of data due to type conversion" и "implicit conversion from 'number' to 'string'

Рис.14. Предупреждения “possible loss of data due to type conversion” и “implicit conversion from ‘number’ to ‘string’

В данном примере компилятор предупреждает о возможной потере точности при присвоении различных типов данных и неявном преобразовании типа int в string.

Для исправления нужно использовать явное приведение типов:

#property strict
void OnStart()
  {
   double a=7;
   float b=(float)a;
   int c=(int)b;
   string str=(string)c;
   Print(c);
  }

3.3. Неиспользуемые переменные

Наличие переменных, которые не используются в коде программы (лишние сущности) не является хорошим тоном.

void OnStart()
  {
   int i,j=10,k,l,m,n2=1;
   for(i=0; i<5; i++) {j+=i;}
  }

Сообщения о таких переменных выводятся вне зависимости от режима компиляции:

Рис.15. Предупреждения "variable '%' not used'

Рис.15. Предупреждения “variable ‘%’ not used’

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

Выводы

В статье рассмотрены типичные проблемы, с которыми могут столкнуться программисты при компиляции старых программ, содержащих ошибки.

Во всех случаях при отладке программ рекомендуется использовать строгий режим компиляции.

Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

Closed

Steviey opened this issue

Jan 13, 2019

· 5 comments

Closed

[RESOLVED] Implicit Conversion Warnings

#10

Steviey opened this issue

Jan 13, 2019

· 5 comments

Assignees

@integracore2

Comments

@Steviey

DWX_ZeroMQ_Server_v2.0.1_RC8

I get a bunch of warnings…actually can’t been overseen…

implicit conversion from ‘number’ to ‘string’ (multiple lines)
declaration of ‘data’ hides global declaration in file […] Z85.mqh (multiple lines)
expression not boolean GlobalVariable.mqh (multiple lines)

By the way, is this server version for Python only?
I can’t find any information, on how to handle the versions in regard to R.
And is it OK to use the old version because of its simple, easy to extend structur?

Thank you.

@TimKabue

Hello Steviey,
The “implicit conversion from ‘number’ to ‘string'” is brought about in mql4 when you convert a number variable to a string variable in your code without explicitly coding it to do that. For example:

int number = 10;
Alert(number);

The above code will throw that warning. Instead, you should convert the the variable ‘number’ of type integer to type string. Like this:

int number = 10;
Alert(string(number));

Use the function string(); to remove those errors.

@TimKabue

@integracore2

Hi @Steviey ,

Thank you for raising this – could you please do the following:

  1. paste a text log of the warnings generated? need to ascertain which files are generating them, the MQL4 script for the EA itself, the dependencies, and/or both.

  2. confirm which version / which file you are referencing here in this issue?

The latest MQL4 EA in v2.0.1_RC8 is language-neutral in the sense that you can implement the sequence of commands and send to the EA via any programming language of choice.

As long as the message is structured as the EA is expecting it in, the sending application could be any ZeroMQ supported language capable of digesting JSON responses.

We have not yet released a version for v2.0.1_RC8 in R, only Python.

Thanks!

@integracore2

[UPDATE] Implicit conversion warnings resolved in an updated DWX_ZeroMQ_Server_v2.0.1_RC8.mq4.

Changes will be committed shortly.

@integracore2
integracore2

changed the title
Bunch of Warnings

[RESOLVED] Bunch of Warnings

Jan 15, 2019

@integracore2

@integracore2
integracore2

changed the title
[RESOLVED] Bunch of Warnings

[RESOLVED] Implicit Conversion Warnings

Jan 15, 2019

Содержание

  1. Помогите избавиться от предупреждений
  2. Why error «possible loss due to conversion», and how to solve this?
  3. Possible loss of data due to type conversion.
  4. Что не так? possible loss of data due to type conversion
  5. Типичные ошибки в программах на MQL4 и методы их устранения
  6. Введение
  7. 1. Ошибки компиляции
  8. 2. Ошибки времени выполнения
  9. 3. Предупреждения компилятора
  10. Выводы

Помогите избавиться от предупреждений

avatar na2

avatar na2

avatar na2

Добрый день имея в коде: #property strict
Прошу вас написать как избавиться от ряда предупреждений:

2) implicit conversion from ‘string’ to ‘number’

3) implicit conversion from ‘string’ to ‘number’

58E3DFDD D3B2

58E3DFDD D3B2

58E3DFDD D3B2

Добрый день имея в коде: #property strict
Прошу вас написать как избавиться от ряда предупреждений:

2) implicit conversion from ‘string’ to ‘number’

3) implicit conversion from ‘string’ to ‘number’

privedenie tipov tipi dannih osnovi 1

608BF208 A707

608BF208 A707

608BF208 A707

Добрый день имея в коде: #property strict
Прошу вас написать как избавиться от ряда предупреждений:

2) implicit conversion from ‘string’ to ‘number’

3) implicit conversion from ‘string’ to ‘number’

Источник

Why error «possible loss due to conversion», and how to solve this?

avatar na2

avatar na2

avatar na2

I have written this small function which helps any programs to do the normalize of prices (without having to re-type the long normalize command), but it keeps giving this error. How can i solve this?

the error is: possible loss of data due to type conversion tstEA.mq5 78 12

if theres any suggestion or work around to this? Thx!

Update: Now I do this (as below), and the error disappears. but is my solution below ok? Will it have any effects later, is what i am worried.

50ED5DEA 958C

50ED5DEA 958C

50ED5DEA 958C

It isn’t an error. It’s just a warning.

I think this topic helps you

avatar na2

avatar na2

avatar na2

It isn’t an error. It’s just a warning.

I think this topic helps you

Yes, i read 70-80% before, thats how I know to do that thing (int).

Thanks for letting me know its not error. Its a huge relief to me. This topic is solved, thanks to your reply.

avatar na2

avatar na2

avatar na2

Very old topic but still some questions.

With (int) I prevent the » possible loss of data due to type conversion». The data type of iVolume is long and therefore takes 8 byte. Does this operation cause it to take only 4 bytes? Or does this additional code (int) increase the memory size. In other words which of these has the best performance: a) or b)?

58CE6BEA 2072

58CE6BEA 2072

58CE6BEA 2072

There is no difference between a) and b) except for the compiler warning.

‘sum’ remains an int; it can’t change.

The compiler is warning you that the long value from iVolume will be put into an int, as there is no other choice. It warns you because you haven’t explicitly asked for this to happen (but it is going to happen nevertheless).

By typecasting, you are instructing it to put the long value into an int. As you have done this explicitly, there is no need for the warning.

Источник

Possible loss of data due to type conversion.

5FDCA8CD 5E01

5FDCA8CD 5E01

5FDCA8CD 5E01

Wondering if someone can assist with troubleshooting an EA that I am currently developing.

I am getting the following error: Possible loss of data due to type conversion.

At the following line:

I have managed to get «past» this issue by swapping OrderOpenTime(); to (int)OrderOpenTime(); but I am noticing during forward testing that after a few entries it stops entering further positions for no reason

Could this be part of the problem? If so, can someone help?

mql5 forum 3

avatar na2

avatar na2

avatar na2

584F20BE 8336

584F20BE 8336

584F20BE 8336

Do you really expect an answer? There are no mind readers here and our crystal balls are cracked. Always post all relevant code (using Code button).
How To Ask Questions The Smart Way. 2004
Be precise and informative about your problem

We can’t possibly know what tradelist is.

Unless you need to sort it (ArraySort)(by time) why do you need to store anything but tickets?

5FDCA8CD 5E01

5FDCA8CD 5E01

5FDCA8CD 5E01

Do you really expect an answer? There are no mind readers here and our crystal balls are cracked. Always post all relevant code (using Code button).
How To Ask Questions The Smart Way. 2004
Be precise and informative about your problem

We can’t possibly know what tradelist is.

Unless you need to sort it (ArraySort)(by time) why do you need to store anything but tickets?

Apologies for this, please find below the full code:

My main problem is there it’s supposed to enter a position after every signal, which it does but after a certain period (no consitent) it stops and doesn’t enter again, sometimes 10 trades sometimes 20 it depends

I am trying to understand why it doesn’t enter anymore, and I know I had an alert about «Possible loss of data due to type conversion» with the following line:

I resolved this by changing it to the following:

But I am still having the same problem where the positions stop stacking after a variable X amount of entries

Источник

Что не так? possible loss of data due to type conversion

5D666C18 632D

5D666C18 632D

5D666C18 632D

Написал декодирование магика, а компиляция ругается. Что ей не нравится?

Тем не менее отрабатывает почти правильно:

5D666C18 632D

5D666C18 632D

5D666C18 632D

Ошибку нашёл. Работает.

Но предупреждения остались. Что ему не нравится?

51CCA017 F44D

51CCA017 F44D

51CCA017 F44D

Все верно не нравится.

num_symbol = StringToInteger (str_symb); // матерится possible loss of data due to type conversion

5D666C18 632D

5D666C18 632D

5D666C18 632D

Блиииин. Голова два уха ))))))))))

6036686D 10A8

6036686D 10A8

6036686D 10A8

У меня вроде с типами все ок, но ругается:

А вот так нормально:

где DIGIT_pair1 должен быть int. Короче не знаю, что сказать. Так всё закручено))

5FD1D540 59A9

5FD1D540 59A9

5FD1D540 59A9

Помогите исправить possible loss of data due to type conversion:

string LowerCase(string value)

for (i = 0; i = 65 && n + 32); // вот тут possible loss of data due to type conversion именно где подчёркнуто

string UpperCase(string value)

for (i = 0; i = 97 && n // вот тут possible loss of data due to type conversion именно где подчёркнуто

5C4F743E FA12

5C4F743E FA12

5C4F743E FA12

У меня вроде с типами все ок, но ругается:

А вот так нормально:

где DIGIT_pair1 должен быть int. Короче не знаю, что сказать. Так всё закручено))

Где то было, что целые числа упрощенно представлены и требуют явного приведения типа или изначально правильного.

других путей не нашел, или явное приведение или изначально правильный тип целого.

Источник

Типичные ошибки в программах на MQL4 и методы их устранения

4B5DE8B4 9045

4B5DE8B4 9045

Введение

При использовании новой версии компилятора языка MQL4 некоторые старые программы могут выдавать ошибки.

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

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

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

1. Ошибки компиляции

При наличии ошибок в коде программа не может быть скомпилирована.

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

Этот режим значительно упрощает поиск ошибок.

1.1. Идентификатор совпадает с зарезервированным словом

Если наименование переменной или функции совпадает с одним из зарезервированных слов:

то компилятор выводит сообщения об ошибках:

Рис.1. Ошибки «unexpected token» и «name expected»

Для исправления данной ошибки нужно исправить имя переменной или функции.

1.2. Специальные символы в наименованиях переменных и функций

Если наименования переменных или функций содержат специальные символы ($, @, точка):

то компилятор выводит сообщения об ошибках:

Рис.2. Ошибки «unknown symbol» и «semicolon expected»

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

1.3. Ошибки использования оператора switch

Старая версия компилятора позволяла использовать любые значения в выражениях и константах оператора switch:

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

Рис.3. Ошибки «illegal switch expression type» и «constant expression is not integral»

В таких случаях можно использовать явные сравнения численных значений, например:

1.4. Возвращаемые значений функций

Все функции, кроме void, должны возвращать значение объявленного типа. Например:

При строгом режиме компиляции (strict) возникает ошибка:

figure 4 error not all control paths return a value

Рис.4. Ошибка «not all control paths return a value»

В режиме компиляции по умолчанию компилятор выводит предупреждение:

figure 5 warning not all control paths return a value

Рис.5. Предупреждение «not all control paths return a value»

Если возвращаемое значение функции не соответствует объявлению:

то при строгом режиме компиляции возникает ошибка:

figure 6 error function must return a value

Рис.6. Ошибка «function must return a value»

В режиме компиляции по умолчанию компилятор выводит предупреждение:

figure 7 warning return function must return a value

Для исправления таких ошибок в код функции нужно добавить оператор возврата return c возвращаемым значением соответствующего типа.

1.5. Массивы в аргументах функций

Массивы в аргументах функций теперь передаются только по ссылке.

Данный код при строгом режиме компиляции (strict) приведет к ошибке:

figure 8 error arrays passed by reference only

Рис.8. Ошибка компилятора «arrays passed by reference only»

В режиме компиляции по умолчанию компилятор выводит предупреждение:

figure 9 warning arrays passed by reference only

Рис.9. Предупреждение компилятора «arrays passed by reference only»

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

Следует отметить, что теперь константные массивы ( Time[], Open[], High[], Low[], Close[], Volume[]) не могут быть переданы по ссылке. Например, вызов:

вне зависимости от режима компиляции приводит к ошибке:

figure 10 constant variable cannot be passed as reference

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

2. Ошибки времени выполнения

Ошибки, возникающие в процессе исполнения кода программы принято называть ошибками времени выполнения (runtime errors). Такие ошибки обычно зависят от состояния программы и связаны с некорректными значениями переменных.

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

2.1. Выход за пределы массива (Array out of range)

Эта ошибка часто возникает в индикаторах при обращении к индикаторным буферам. Функция IndicatorCounted() возвращает количество баров, неизменившихся после последнего вызова индикатора. Значения индикаторов на уже рассчитанных ранее барах не нуждаются в пересчете, поэтому для ускорения расчетов достаточно обрабатывать только несколько последних баров.

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

Часто встречается некорректная обработка случая counted_bars==0 (начальную позицию limit нужно уменьшить на значение, равное 1 + максимальный индекс относительно переменной цикла).

Также следует помнить о том, что в момент исполнения функции start() мы можем обращаться к элементам массивов индикаторных буферов от 0 до Bars()-1. Если есть необходимость работы с массивами, которые не являются индикаторными буферами, то их размер следует увеличить при помощи функции ArrayResize() в соответствии с текущим размером индикаторных буферов. Максимальный индекс элемента для адресации также можно получить вызовом ArraySize() с одним из индикаторных буферов в качестве аргумента.

2.2. Деление на ноль (Zero divide)

Ошибка «Zero divide» возникает в случае, если при выполнении операции деления делитель оказывается равен нулю:

При выполнении данного скрипта во вкладке «Эксперты» возникает сообщение об ошибке и завершении работы программы:

figure 11 error zero divide

Рис.11. Сообщение об ошибке «zero divide»

Обычно такая ошибка возникает в случаях, когда значение делителя определяется значениями каких-либо внешних данных. Например, если анализируются параметры торговли, то величина задействованной маржи оказывается равна 0 если нет открытых ордеров. Другой пример: если анализируемые данные считываются из файла, то в случае его отсутствия нельзя гарантировать корректную работу. По этой причине желательно стараться учитывать подобные случаи и корректно их обрабатывать.

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

figure 12 incorrect divisor message

Рис. 12. Сообщение о некорректном значении делителя

2.3. Использование 0 вместо NULL для текущего символа

В старой версии компилятора допускалось использование 0 (нуля) в качестве аргумента в функциях, требующих указания финансового инструмента.

Например, значение технического индикатора Moving Average для текущего символа можно было запрашивать следующим образом:

В новом компиляторе для указания текущего символа нужно явно указывать NULL:

Кроме того, текущий символ и период графика можно указать при помощи функций Symbol() и Period().

2.4. Строки в формате Unicodе и их использование в DLL

Строки теперь представляют собой последовательность символов Unicode.

Следует учитывать этот факт и использовать соответствующие функции Windows. Например, при использовании функций библиотеки wininet.dll вместо InternetOpenA() и InternetOpenUrlA () следует вызывать InternetOpenW() и InternetOpenUrlW().

В MQL4 изменилась внутренняя структура строк (теперь она занимает 12 байт), поэтому при передаче строк в DLL следует использовать структуру MqlString:

2.5. Совместное использование файлов

В новом MQL4 при открытии файлов необходимо явно указывать флаги FILE_SHARE_WRITE и FILE_SHARE_READ для совместного использования.

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

Например, при работе с оффлайновыми графиками требуется явно указывать флаги совместного доступа:

Подробности можно найти в статье в статье «Оффлайновые графики и новый MQL4«.

2.6. Особенность преобразования datetime

Следует иметь ввиду, что преобразование типа datetime в строку теперь зависит от режима компиляции:

Например, попытка работы с файлами, имя которых содержит двоеточие, приведет к ошибке.

3. Предупреждения компилятора

Чистый код не должен содержать предупреждений.

3.1. Пересечения имен глобальных и локальных переменных

Если на глобальном и локальном уровнях присутствуют переменные с одинаковыми именами:

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

figure 13 declaration of hides global declaration at line

Рис.13. Предупреждение «declaration of ‘%’ hides global declaration at line %»

Для исправления таких предупреждений нужно скорректировать имена глобальных переменных.

3.2. Несоответствие типов

В новой версии компилятора в ведена операция приведения типов.

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

figure 14 possible loss of data due to type conversion implicit conversion from number to string

Рис.14. Предупреждения «possible loss of data due to type conversion» и «implicit conversion from ‘number’ to ‘string’

В данном примере компилятор предупреждает о возможной потере точности при присвоении различных типов данных и неявном преобразовании типа int в string.

Для исправления нужно использовать явное приведение типов:

3.3. Неиспользуемые переменные

Наличие переменных, которые не используются в коде программы (лишние сущности) не является хорошим тоном.

Сообщения о таких переменных выводятся вне зависимости от режима компиляции:

figure 15 warning variable not used

Рис.15. Предупреждения «variable ‘%’ not used’

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

Выводы

В статье рассмотрены типичные проблемы, с которыми могут столкнуться программисты при компиляции старых программ, содержащих ошибки.

Во всех случаях при отладке программ рекомендуется использовать строгий режим компиляции.

Источник

txtAddress.Text = DB.ProfileDataset.Tables("tblCustomers").Rows.Item("Address").toString

The above code generated Option Strict On disallows implicit conversions from ‘String’ to ‘Integer’ error under the Item(“Address”)
I don’t know what i did wrong…

Philip Fourie's user avatar

asked Feb 6, 2010 at 17:24

user133466's user avatar

The DataRowCollection.Item property requires an integer for the row index.

I think you are after the following syntax:

txtAddress.Text = DB.ProfileDataset.Tables("tblCustomers").Rows(0)("Address").ToString()

EDIT

Something to keep in mind:

original code
    = DB.ProfileDataset.Tables("tblCustomers").Rows.Item("Address").toString
compiler sees
    = DB.ProfileDataset.Tables.Item("tblCustomers").Rows.Item("Address").toString
fixed code
    = DB.ProfileDataset.Tables("tblCustomers").Rows(0)("Address").ToString()
compiler sees
    = DB.ProfileDataset.Tables.Item("tblCustomers").Rows.Item(0).Item("Address").ToString()

Jonathan Allen's user avatar

answered Feb 6, 2010 at 17:29

Philip Fourie's user avatar

Philip FouriePhilip Fourie

110k10 gold badges62 silver badges83 bronze badges

Добавить комментарий