Предложение - явное приведение к datetime - страница 2

 
Georgiy Merts:

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

Некорректно выдрано из контекста.

В данном случае - ситуация схожая. Или такой пример. Какой-нибудь ID, в котором разряды старше 32 что-то обозначают. Процедура написана, все нормально работает. А потом - я ее решил использовать, забыв про старшие разряды, передав ей uint. Процедура-то ждет, что в старших разрядах есть информация, а в инте - ее нет. И вылезти проблема может далеко не сразу.

Никому же не мешает, что мэджики ордеров могут быть отрицательными.

Сейчас с предупреждениями все отлично. Например, при написании кроссплатформенного кода будут возникать предупреждения  (не без оснований) с тикетами и мэджиками.

Чтобы в этой связи любые потери/ошибки учитывать и было сделано

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Библиотеки: MT4Orders

fxsaber, 2018.03.06 09:26

// Список изменений:
// 06.03.2018
//   Add: Добавлены TICKET_TYPE и MAGIC_TYPE, чтобы можно было писать единый кроссплатформенный код
//        без предупреждений компиляторов (включая strict-режим MQL4).

Ниже код, который компилируется без предупреждений под MQL4/5

#property strict

#include <MT4Orders.mqh>

void OnStart()
{
//  long Ticket = 0;
//  long Magic = 0;
  TICKET_TYPE Ticket = 0;
  MAGIC_TYPE  Magic = 0;
  
  long Tmp = OrderSelect(Ticket, SELECT_BY_TICKET) + 
             OrderDelete(Ticket) +
             OrderCloseBy(Ticket, Ticket) +
             OrderClose(Ticket, 1, 0, 0) +    
             OrderSend(_Symbol, OP_BUY, 1, 0, 0, 0, 0, NULL, Magic);
}

Спасибо @Andrey Voytenko за предложение такого решения!

 
fxsaber:

Некорректно выдрано из контекста.

Никому же не мешает, что мэджики ордеров могут быть отрицательными.

Сейчас с предупреждениями все отлично. Например, при написании кроссплатформенного кода будут возникать предупреждения  (не без оснований) с тикетами и мэджиками.

Чтобы в этой связи любые потери/ошибки учитывать и было сделано

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

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

 
Georgiy Merts:

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

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

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

 
fxsaber:

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

Можно. Но, тут не введешь предупреждение. А когда у нас datetime и long - можно. Кстати, насколько я понимаю, datetime - это, по смыслу беззнаковое длинное. ulong, а вовсе не long - число секунд не может быть отрицательным.

А проблема - опять же, напомню тебе код, который ты сам и предложил. Я его себе, кстати, в библиотеку забрал. Но, добавил там несколько ASSERT'ов, как раз для того, чтобы его можно было бы использовать исключительно так, как задумывалось.

 

fxsaber
:

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

Вреда от этого будет больше, чем пользы:

void f(datetime& time)  { }


void Main()
{
  long a = 0;
  f((datetime)a);  // '(datetime)' - parameter passed as reference, variable expected
}

Это не разные типы, а один и тот же.

Вы вероятно путаете понятие типа и битового представление в памяти.  Это разные вещи.  Тип - это интерпретация данных на этапе компиляции. 

Глупо отрицать преимущества строгой типизации.  Это залог надёжного и качественного кода.  Вот объясните мне, зачем вам нужно отправлять вместо datetime какой-то числовой параметр без явного приведения?  Неужели вы не понимаете, что это плохой стиль программирования?

 
void OnStart()
{
  datetime Time1 = -1;
  datetime Time2 = 1;
  int i = -1;
  uint i2 = -1;
  long l = -1;
  ulong l2 = -1;
  
  Print(Time1 * i);  // 1970.01.01 00:00:01
  Print(Time1 * i2); // wrong datetime
  
  Print(Time1 * l);  // 1
  Print(Time1 * l2); // 1
  
  Print(Time2 * i);  // wrong datetime
  Print(Time2 * i2); // 2106.02.07 06:28:15
  
  Print(Time2 * l);  // -1
  Print(Time2 * l2); // 18446744073709551615
}
 
Alexey Navoykov:

Вреда от этого будет больше, чем пользы:

По-моему, это выглядит полезно.

Вы вероятно путаете понятие типа и битового представление в памяти.  Это разные вещи.  Тип - это интерпретация данных на этапе компиляции. 

Мне удобно работать с datetime в нынешнем виде. Ошибок не совершаю. datetime - long.

datetime t = 0;
long l = t; 
int i = t;       // possible loss of data due to type conversion - strict
double d = 0;
datetime t2 = d; // possible loss of data due to type conversion

Глупо отрицать преимущества строгой типизации.  Это залог надёжного и качественного кода.  Вот объясните мне, зачем вам нужно отправлять вместо datetime какой-то числовой параметр без явного приведения?  Неужели вы не понимаете, что это плохой стиль программирования?

Не понимаю. инт к лонгу приводится без предупреждений.

 
Georgiy Merts:

насколько я понимаю, datetime - это, по смыслу беззнаковое длинное. ulong, а вовсе не long - число секунд не может быть отрицательным.

datetime - это именно long.

void OnStart()
{
  datetime t = -1;
  ulong l = -1;
  
  Print(t < 0); // true
  Print(l < 0); // false
}


А вот причина этого предупреждения мне не ясна

long l = 0;
datetime d = l; // possible loss of data due to type conversion
Это, видимо, рудимент - когда datetime был int-ом.
 
Не заиграйтесь в безопасность, от неё и стошнить может. Так и до bool дойдёт и до double. Я недавно приятно был удивлён, когда увидел, что такая конструкция не создаёт предупреждения о добивки размера до байта, всегда вызывала рвотный рефлекс:
struct S
{
   static void f();
}
Лучше флаг -Wparanoia
 
pavlick_:
Я недавно приятно был удивлён, когда увидел, что такая конструкция не создаёт предупреждения о добивки размера до байта, всегда вызывала рвотный рефлекс

Действительно, убрали.

Причина обращения: