Вот такое встретилось, build 1881. Что бы это значило?
2018.08.05 20:40:38.345 TestArray (GBPUSD,M1) iArr[i++] 7 i=6, 6 i=5, 5 i=4, 4 i=3, 3 i=2, 2 i=1, 1 i=0, 1
А 8 где?
А 8 где?
То-то и оно, могу только подозревать, потому, что в конце принта у последнего элемента массива не проставлен i++, а просто i. Да изврат какой-то, буду в СД писать попозже, если никто не ответит.
Вот такое встретилось, build 1881. Что бы это значило?
2018.08.05 20:40:38.345 TestArray (GBPUSD,M1) iArr[i++] 7 i=6, 6 i=5, 5 i=4, 4 i=3, 3 i=2, 2 i=1, 1 i=0, 1
Припоминаю, что при вызовах функций конкатенации строк с несколькими аргументами перед вызовом операции конкатенации в ее аргументах, если есть выполнимые команды, они выполняются в порядке справа налево по аргументам, то есть сначала в самом последнем, затем в предыдущем и т.д. Значит, и в Print так же, i для самого левого аргумента (операнда) имеет наибольшее значение, после выполнения всех i++.
На чем основано данное умозаключение?
Поиск в гугле по запросу " при вызовах функций конкатенации строк с несколькими аргументами" такого не приводит.
На чем основано данное умозаключение?
Поиск в гугле по запросу " при вызовах функций конкатенации строк с несколькими аргументами" такого не приводит.
Я тоже такого не встречал ни в С++, ни в MQL4/5.
Еще немного добавил принтов
#define ARR_SIZE 8 void OnStart() { int iArr[ARR_SIZE] = {1,2,3,4,5,6,7,8}; int i = 0; Print("iArr[i++]"," ", iArr[i++], " i=", i, ", ", iArr[i++], " i=", i, ", ", iArr[i++], " i=", i, ", ", iArr[i++], " i=", i, ", ", iArr[i++], " i=", i, ", ", iArr[i++], " i=", i, ", ", iArr[i++], " i=", i, ", ", iArr[i]); i = 0; Print("iArr[i]"," ", iArr[i], " i=", i++, ", ", iArr[i], " i=", i++, ", ", iArr[i], " i=", i++, ", ", iArr[i], " i=", i++, ", ", iArr[i], " i=", i++, ", ", iArr[i], " i=", i++, ", ", iArr[i], " i=", i++, ", ", iArr[i]); Print("iArr[0..7]"," ",iArr[0], ", ",iArr[1], ", ",iArr[2], ", ",iArr[3], ", ",iArr[4], ", ",iArr[5], ", ",iArr[6], ", ",iArr[7]); }
2018.08.05 22:02:58.218 TestArray (GBPUSD,M1) iArr[i++] 7 i=6, 6 i=5, 5 i=4, 4 i=3, 3 i=2, 2 i=1, 1 i=0, 1
2018.08.05 22:02:58.218 TestArray (GBPUSD,M1) iArr[i] 8 i=6, 7 i=5, 6 i=4, 5 i=3, 4 i=2, 3 i=1, 2 i=0, 1
2018.08.05 22:02:58.218 TestArray (GBPUSD,M1) iArr[0..7] 1, 2, 3, 4, 5, 6, 7, 8
Припоминаю, что при вызовах функций конкатенации строк с несколькими аргументами перед вызовом операции конкатенации в ее аргументах, если есть выполнимые команды, они выполняются в порядке справа налево по аргументам, то есть сначала в самом последнем, затем в предыдущем и т.д. Значит, и в Print так же, i для самого левого аргумента (операнда) имеет наибольшее значение, после выполнения всех i++.
Да, верно.
Значения помещаются в стек вызова функций с последнего параметра.
Не надо строить сложные взаимозависимые вычисляемые выражения в параметрах.
В С++ похожие приколы будут. Причем в зависимости от оптимизатора Debug/Release сборок могут выдаваться разные значения.
Пример:
int _tmain(int argc, _TCHAR* argv[]) { int iArr[8] ={ 1,2,3,4,5,6,7,8 }; volatile int i=0; printf("Results: %d %d\n",iArr[i++],iArr[i++]); return(0); }
В VS2017:
в релизе оптимизатор посчитал себя умным(да, это явная ошибка компилятора!) даже при наличии volatile квалификатора и выдал одинаковый результат: Results: 1 1 в дебаг сборке оптимизатора нет и вычисления идут как задумал(пусть даже он наоборот думал) автор: Results: 2 1
Как видите, в C++ тоже обратный порядок. Как и в MQL5.
Это же классическое правило С.
Аргументы в функцию передаются с конца.
void OnStart() { int x = 7; Print(++x, " ", ++x); }
Это же классическое правило С.
по стандарту С++ порядок вычисления аргументов UB
Да, верно.
Значения помещаются в стек вызова функций с последнего параметра.
Не надо строить сложные взаимозависимые вычисляемые выражения в параметрах.
В С++ похожие приколы будут. Причем в зависимости от оптимизатора Debug/Release сборок могут выдаваться разные значения.
Пример:
В VS2017:
Как видите, в C++ тоже обратный порядок. Как и в MQL5.
Все это тяжелое наследие Си, когда здравый смысл приносился в угоду производительности. Фактически, все что надо, это чтобы компилятор собирал выходную строку Print не так, как ее вычисляемые параметры положили в стек, а как принято читать/писать в западной культуре - слева направо. Это правило явно придумали какие-то арабские программисты, ведь у них все наоборот - справа налево )) Значит, в случае с вычисляемыми выражениями надо формировать строку самому, например такими путями (это я для новичков, конечно):
#define ARR_SIZE 8 void OnStart() { int iArr[ARR_SIZE] = {1,2,3,4,5,6,7,8}; string str = "iArr string formed by a cycle: "; for(int n = 0; n < ARR_SIZE; n++) { str += IntegerToString(iArr[n]); str += (n < ARR_SIZE - 1) ? ", " : ""; } Print(str); i = 0; Print("iArr[i++] with concatente " + iArr[i++] + " i=" + i + ", " + iArr[i++] + " i=" + i + ", "+ iArr[i++] + " i=" + i + ", "+ iArr[i++] + " i=" + i + ", " + iArr[i++] + " i=" + i + ", "+ iArr[i++] + " i=" + i + ", " + iArr[i++] + " i=" + i + ", " + iArr[i]); } 2018.08.06 03:35:47.181 TestArray (EURUSD,M5) iArr string formed by a cycle: 1, 2, 3, 4, 5, 6, 7, 8 2018.08.06 03:35:47.181 TestArray (EURUSD,M5) iArr[i++] with concatente 1 i=1, 2 i=2, 3 i=3, 4 i=4, 5 i=5, 6 i=6, 7 i=7, 8
Во втором случае имеем 15 варнингов "implicit conversion from 'number' to 'string'", а если вставлять везде IntegerToString(iArr[i++]) и IntegerToString(i), то строка станет совсем нечитаема.
Надо еще проверить на "кошерном" C#, неужели и там так же?
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Вот такое встретилось, build 1881. Что бы это значило?
2018.08.05 20:40:38.345 TestArray (GBPUSD,M1) iArr[i++] 7 i=6, 6 i=5, 5 i=4, 4 i=3, 3 i=2, 2 i=1, 1 i=0, 1