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.2. Специальные символы в наименованиях переменных и функций
- 1.3. Ошибки использования оператора switch
- 1.4. Возвращаемые значения у функций
- 1.5. Массивы в аргументах функций
- Ошибки времени выполнения
- 2.1. Выход за пределы массива (Array out of range)
- 2.2. Деление на ноль (Zero divide)
- 2.3. Использование 0 вместо NULL для текущего символа
- 2.4. Строки в формате Unicodе и их использование в DLL
- 2.5. Совместное использование файлов
- 2.6. Особенность преобразования datetime
- Предупреждения компилятора
- 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.2. Специальные символы в наименованиях переменных и функций
Если наименования переменных или функций содержат специальные символы ($, @, точка):
int $var1; int @var2; int var.3; void f@() { return; }
то компилятор выводит сообщения об ошибках:
Рис.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”
В таких случаях можно использовать явные сравнения численных значений, например:
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”
В режиме компиляции по умолчанию компилятор выводит предупреждение:
Рис.5. Предупреждение “not all control paths return a value”
Если возвращаемое значение функции не соответствует объявлению:
int init() { return; }
то при строгом режиме компиляции возникает ошибка:
Рис.6. Ошибка “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”
В режиме компиляции по умолчанию компилятор выводит предупреждение:
Рис.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
Для устранения подобных ошибок нужно скопировать необходимые данные из константного массива:
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”
Обычно такая ошибка возникает в случаях, когда значение делителя определяется значениями каких-либо внешних данных. Например, если анализируются параметры торговли, то величина задействованной маржи оказывается равна 0 если нет открытых ордеров. Другой пример: если анализируемые данные считываются из файла, то в случае его отсутствия нельзя гарантировать корректную работу. По этой причине желательно стараться учитывать подобные случаи и корректно их обрабатывать.
Самый простой способ – проверять делитель перед операцией деления и выводить сообщение об некорректном значении параметра:
void OnStart() { int a=0, b=0,c; if(b!=0) {c=a/b; Print(c);} else {Print("Error: b=0"); return; }; }
В результате критической ошибки не возникает, но выводится сообщение о некорректном значении параметра и работа завершается:
Рис. 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 %”
Для исправления таких предупреждений нужно скорректировать имена глобальных переменных.
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’
В данном примере компилятор предупреждает о возможной потере точности при присвоении различных типов данных и неявном преобразовании типа 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’
Для исправления нужно убрать неиспользуемые переменные из кода программы.
Выводы
В статье рассмотрены типичные проблемы, с которыми могут столкнуться программисты при компиляции старых программ, содержащих ошибки.
Во всех случаях при отладке программ рекомендуется использовать строгий режим компиляции.
Предупреждение: все права на данные материалы принадлежат 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
Comments
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.
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.
Hi @Steviey ,
Thank you for raising this – could you please do the following:
-
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.
-
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!
[UPDATE] Implicit conversion warnings resolved in an updated DWX_ZeroMQ_Server_v2.0.1_RC8.mq4.
Changes will be committed shortly.
integracore2
changed the title
Bunch of Warnings
[RESOLVED] Bunch of Warnings
Jan 15, 2019
integracore2
changed the title
[RESOLVED] Bunch of Warnings
[RESOLVED] Implicit Conversion Warnings
Jan 15, 2019
Содержание
- Помогите избавиться от предупреждений
- Why error «possible loss due to conversion», and how to solve this?
- Possible loss of data due to type conversion.
- Что не так? possible loss of data due to type conversion
- Типичные ошибки в программах на MQL4 и методы их устранения
- Введение
- 1. Ошибки компиляции
- 2. Ошибки времени выполнения
- 3. Предупреждения компилятора
- Выводы
Помогите избавиться от предупреждений
Добрый день имея в коде: #property strict
Прошу вас написать как избавиться от ряда предупреждений:
2) implicit conversion from ‘string’ to ‘number’
3) implicit conversion from ‘string’ to ‘number’
Добрый день имея в коде: #property strict
Прошу вас написать как избавиться от ряда предупреждений:
2) implicit conversion from ‘string’ to ‘number’
3) implicit conversion from ‘string’ to ‘number’
Добрый день имея в коде: #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?
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.
It isn’t an error. It’s just a warning.
I think this topic helps you
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.
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)?
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.
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?
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?
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
Написал декодирование магика, а компиляция ругается. Что ей не нравится?
Тем не менее отрабатывает почти правильно:
Ошибку нашёл. Работает.
Но предупреждения остались. Что ему не нравится?
Все верно не нравится.
num_symbol = StringToInteger (str_symb); // матерится possible loss of data due to type conversion
Блиииин. Голова два уха ))))))))))
У меня вроде с типами все ок, но ругается:
А вот так нормально:
где DIGIT_pair1 должен быть int. Короче не знаю, что сказать. Так всё закручено))
Помогите исправить 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 именно где подчёркнуто
У меня вроде с типами все ок, но ругается:
А вот так нормально:
где DIGIT_pair1 должен быть int. Короче не знаю, что сказать. Так всё закручено))
Где то было, что целые числа упрощенно представлены и требуют явного приведения типа или изначально правильного.
других путей не нашел, или явное приведение или изначально правильный тип целого.
Источник
Типичные ошибки в программах на MQL4 и методы их устранения
Введение
При использовании новой версии компилятора языка 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) возникает ошибка:
Рис.4. Ошибка «not all control paths return a value»
В режиме компиляции по умолчанию компилятор выводит предупреждение:
Рис.5. Предупреждение «not all control paths return a value»
Если возвращаемое значение функции не соответствует объявлению:
то при строгом режиме компиляции возникает ошибка:
Рис.6. Ошибка «function must return a value»
В режиме компиляции по умолчанию компилятор выводит предупреждение:
Для исправления таких ошибок в код функции нужно добавить оператор возврата return c возвращаемым значением соответствующего типа.
1.5. Массивы в аргументах функций
Массивы в аргументах функций теперь передаются только по ссылке.
Данный код при строгом режиме компиляции (strict) приведет к ошибке:
Рис.8. Ошибка компилятора «arrays passed by reference only»
В режиме компиляции по умолчанию компилятор выводит предупреждение:
Рис.9. Предупреждение компилятора «arrays passed by reference only»
Для исправления таких ошибок нужно явно указать передачу массива по ссылке, добавив префикс & перед именем массива:
Следует отметить, что теперь константные массивы ( Time[], Open[], High[], Low[], Close[], Volume[]) не могут быть переданы по ссылке. Например, вызов:
вне зависимости от режима компиляции приводит к ошибке:
Для устранения подобных ошибок нужно скопировать необходимые данные из константного массива:
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» возникает в случае, если при выполнении операции деления делитель оказывается равен нулю:
При выполнении данного скрипта во вкладке «Эксперты» возникает сообщение об ошибке и завершении работы программы:
Рис.11. Сообщение об ошибке «zero divide»
Обычно такая ошибка возникает в случаях, когда значение делителя определяется значениями каких-либо внешних данных. Например, если анализируются параметры торговли, то величина задействованной маржи оказывается равна 0 если нет открытых ордеров. Другой пример: если анализируемые данные считываются из файла, то в случае его отсутствия нельзя гарантировать корректную работу. По этой причине желательно стараться учитывать подобные случаи и корректно их обрабатывать.
В результате критической ошибки не возникает, но выводится сообщение о некорректном значении параметра и работа завершается:
Рис. 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. Пересечения имен глобальных и локальных переменных
Если на глобальном и локальном уровнях присутствуют переменные с одинаковыми именами:
то компилятор выводит предупреждение и укажет номер строки, на которой объявлена глобальная переменная:
Рис.13. Предупреждение «declaration of ‘%’ hides global declaration at line %»
Для исправления таких предупреждений нужно скорректировать имена глобальных переменных.
3.2. Несоответствие типов
В новой версии компилятора в ведена операция приведения типов.
В строгом режиме компиляции при несоответствии типов компилятор выводит предупреждения:
Рис.14. Предупреждения «possible loss of data due to type conversion» и «implicit conversion from ‘number’ to ‘string’
В данном примере компилятор предупреждает о возможной потере точности при присвоении различных типов данных и неявном преобразовании типа int в string.
Для исправления нужно использовать явное приведение типов:
3.3. Неиспользуемые переменные
Наличие переменных, которые не используются в коде программы (лишние сущности) не является хорошим тоном.
Сообщения о таких переменных выводятся вне зависимости от режима компиляции:
Рис.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…
asked Feb 6, 2010 at 17:24
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()
answered Feb 6, 2010 at 17:29
Philip FouriePhilip Fourie
110k10 gold badges62 silver badges83 bronze badges