Разработчикам: Некорректно работает инициилизация массива строк в библиотеке.

 
Описываю подробно, поскольку ошибка неочевидная, но у меня она абсолютно стабильная.

Приведенный пример - урезанная часть программы.

структура программы : "\scripts\test2.mq4"
                                   "\include\stdio2.mqh"
                                   "\libraries\stdio2.mq4"

"\scripts\test2.mq4"
//+-----------------------------------------------------------------------------+
//|                                                                    test.mq4 |
//|                                       Copyright © 2007, DMAN Software Corp. |
//|                                                          DmanHome@yandex.ru |
//+-----------------------------------------------------------------------------+
 
#property copyright "Copyright © 2007, DMAN Software Corp."
#property link      "DmanHome@yandex.ru"
 
// заголовочные файлы
#include <stdio2.mqh>
 
#define PROG_NAME "test"
 
int    logID;          // описание log-файла
string logName;        //
 
 
int init()
{
  Comment("Начали...");
 
  // инициилизация Log-файла
  logName = StringConcatenate(PROG_NAME, "\\", PROG_NAME, "_2007.09.15.log");
 
  logID = FioInit(logName, FILE_READ | FILE_WRITE, SEEK_END);
 
  // чтение стандартного INI-файла
  string iniSymName = StringConcatenate(PROG_NAME, "\\", "symRates.ini");
 
  int    iniID = FioInit(iniSymName, FILE_READ | FILE_WRITE, SEEK_END);
 
  return (0);
}
 
 
int deinit()
{
//    FioDeinit();
 
  Comment("Готово");
 
  return (0);
}
 
 
int start()
{
// Заголовок начало
  static bool firstTime = true;
 
    if (!firstTime)
    return(0);
  firstTime = false;
// Заголовок конец
 
    return(0);
}

"\include\stdio2.mqh"
//+-----------------------------------------------------------------------------+
//|                                                                   stdio.mqh |
//|                                       Copyright © 2007, DMAN Software Corp. |
//|                                                          DmanHome@yandex.ru |
//+-----------------------------------------------------------------------------+
 
#import "stdio2.ex4"
 
// ************ Обмен с файлами ************
int    FioInit(string fName, int openMode, int seekMode);
 
#import

"\libraries\stdio2.mq4"
//+-----------------------------------------------------------------------------+
//|                                                                   stdio.mq4 |
//|                                       Copyright © 2007, DMAN Software Corp. |
//|                                                          DmanHome@yandex.ru |
//+-----------------------------------------------------------------------------+
 
#property copyright "Copyright © 2007, DMAN Software Corp."
#property link      "DmanHome@yandex.ru"
#property library
 
//Максимальное количество одновременно открытых файлов (<= 32)
#define FIO_CNT  3
 
int fioID,              // индекс файла текущего вывода (от 0 до FIO_CNT - 1)
    fioHandle[FIO_CNT]; // handle файла вывода
 
string fioName[FIO_CNT];     // имя файла вывода
 
 
int FioInit(string fName, int openMode, int seekMode)
{
    static bool firstTime = true;
    int i, I;
 
    // начальная инициилизация массивов
    if (firstTime)
    {
        firstTime = false;
        fioID  = 0;
        for (i = 0; i < FIO_CNT; i++)
        {
            fioHandle[i] = -1;
            fioName[i]   = "";
        }
    }
 
// отладочный вывод
string str = "До : " + fName;
for (i = 0; i < FIO_CNT; i++)
  str = StringConcatenate(str, "\n", i, " : ", fioName[i]);
 
Comment(str);
Print(str);
Sleep(3000);
// отладочный вывод
 
    // выделяем элементы массивов под описатели файла с проверкой
    for (I = 0; I < FIO_CNT; I++)
    if (fioHandle[I] == -1)
          break;
 
    if (I == FIO_CNT)
    {
//    myLastError = 119; // Слишком много файлов.
        return (-1);
    }
 
    //открываем файл (заглушка)
  fioHandle[I] = I + 1;
    fioID      = I;
  fioName[I] = fName;
 
// отладочный вывод
str = "После : " + fName;
for (i = 0; i < FIO_CNT; i++)
  str = StringConcatenate(str, "\n", i, " : ", fioName[i]);
 
Comment(str);
Print(str);
Sleep(3000);
// отладочный вывод
 
    return(I); // возврат ID - индекса элемента массива, хранящего хэндл.
}


Проблема: массив строк fioName[FIO_CNT] в модуле "stdio2.mq4" - внешний по отношению к функции FioInit() и по логике программы при каждом обращении к FioInit() в нем сохраняется новое значение, при этом старые значения должны оставаться.
Реально старые значения забиваются новыми даже еще до операции присвоения значения элементу массива fioName[].
Это видно из вывода в log-файл двукратного обращения к функции FioInit().
Каждый раз выводится весь массив fioName[] из 3-х элементов - имен неких файлов,

"До :" - до нового присвоения значения элементу массива fioName[],
"После :" - после присвоения.

из log-файла:                                        Должно быть по моему мнению:
                                                
До : test\test_2007.09.15.log                  До : test\test_2007.09.15.log
0 :                                                        0 :
1 :                                                        1 :
2 :                                                        2 :
После : test\test_2007.09.15.log             После : test\test_2007.09.15.log
0 : test\test_2007.09.15.log                    0 : test\test_2007.09.15.log
1 :                                                        1 :
2 :                                                        2 :
                                                 
До : test\symRates.ini                            До : test\symRates.ini
0 : test\symRates.ini                               0 : test\test_2007.09.15.log
1 :                                                         1 :
2 :                                                         2 :
После : test\symRates.ini                        После : test\symRates.ini
0 : test\symRates.ini                               0 : test\test_2007.09.15.log
1 : test\symRates.ini                               1 : test\symRates.ini
2 :                                                         2 :

Правильный вывод обеспечивается включением содержательной части файла "stdio2.mq4" в файл "test2.mq4", т.е. отказ от библиотеки функций.
Такой вариант приведен в файле "test.mq4" (Fails.zip), но для большой программы это чревато потенциальным увеличением моих ошибок и мне это не очень нравится.

На всякий случай в Fails.zip я вложил и ex4 файлы.

Информация о праграмме:

MetaTrader 4.00 build 210


Информация о системе:

[Сведения о системе]

Элемент Значение
Имя ОС Microsoft Windows XP Professional
Версия 5.1.2600 Service Pack 1 Сборка 2600
Изготовитель ОС Microsoft Corporation
Имя системы DMAN
Изготовитель GBT___
Модель AWRDACPI
Тип Компьютер на базе X86
Процессор x86 Family 15 Model 3 Stepping 4 GenuineIntel ~2813 МГц
Версия BIOS Award Software International, Inc. F1, 08.01.2004
Версия SMBIOS 2.3
Папка Windows C:\WINDOWS
Системная папка C:\WINDOWS\System32
Устройство загрузки \Device\HarddiskVolume1
Язык Россия
Аппаратно-зависимый уровень (HAL) Версия = "5.1.2600.1106 (xpsp1.020828-1920)"
Имя пользователя DMAN\Дима
Часовой пояс Russian Standard Time
Полный объем физической памяти 512.00 МБ
Доступно физической памяти 235.34 МБ
Всего виртуальной памяти 1.72 ГБ
Доступно виртуальной памяти 1.19 ГБ
Файл подкачки 1.22 ГБ
Файл подкачки C:\pagefile.sys
Файлы:
fails.zip  9 kb
 
А Вы не забыли поставить фигурные скобки для оформления блока после:
// выделяем элементы массивов под описатели файла с проверкой
    for (I = 0; I < FIO_CNT; I++)
 
Renat, не ожидал, что Вы так быстро среагируете. Приятно. Сам раньше посмотреть не мог.

Отвечаю на ваше замечание.
Первое - признаться про фигурные скобки я не забыл и считаю, что они здесь не обязательны.
По моему мнению проблема начинается раньше этого места и, возможно, она существует уже в момент старта функции FioInit().
Однако, как честный исследователь я тут же проверил ваше замечание -  не помогло.
 
Я проверил - вместо нулевого элемента появляется значение fName. Похоже, что это ошибка оптимизатора при работе со строками.
В понедельник детально разберемся и исправим.

Спасибо за найденную ошибку и демонстрационный код.
 

Ошибку передачи строк в mql4-библиотеку исправили. Спасибо за предоставленный пример.

 
Мне нравится ваша программа и ваша работа.
Сам когдато и создавал и сопровождал программы.
Рад, что сумел Вам помочь.
Причина обращения: