エラー、バグ、質問 - ページ 1576

 

このバナー、どういう原理で製品が貼られているのだろう。

また、正規販売店の製品はそちらに行くのでしょうか?というか、このバナーで自分の商品が見られるのでしょうか? 30ページめくっても、自分のものが見当たりません...。

 
Renat Fatkhullin:

私は干渉しない。私は26年間、ノンストップでプログラミングを続けてきました。

警告は、金融分野の話であれば、基本的にエラーになります。そして、「符号の消失、精度の 低下、ゴーストに関する損失など」に関する何千もの報告はすべて、コードの品質に対する評決です。どうやら、その意味をよく理解していないようですね。

コンパイラがエラーとして指摘したコードの一部を十分に充実した形で提供してください。

それがないと、この議論は見苦しく、不公平に見えてしまうのです。

レナート、「コードの品質」についての議論は、今回のテーマとは関係ありません。 ここでは、コンパイラビリティ、すなわちコードの作業性についてだけ話しているのですから。そして、精度の低下など。- これはプログラマーの個人的な問題であり、いわばプログラマーの責任である。intからshortへの暗黙の変換などは、言語規格で禁止されていませんよね。 それなのに、なぜ今になって説教をするのでしょうか?

よし、このバグの一つを見つけたぞ。

class CClass
{

};


class CArr
{
  CClass* data[];
 public: 
  CClass* operator[] (int i)  { return data[i]; }
};


template<typename T>
void Func (T* obj)      {  }
 

void OnStart()
{  
  CArr arr;
  Func(arr[0]);
}

というログが出ます。

'CClass' - 型のない宣言 TestScript.mq5 16 9
'CClass' - カンマが必要 TestScript.mq5 16 9

以前のビルドでは、すべてがうまくいっていました。

 
Alexey Navoykov:

レナート、「コードの品質」についての議論は、今回のテーマとは無関係だ。 ここでは、コンパイラビリティ、つまりコードの実行可能性についてだけ話しているのだから。そして、精度の低下など。- これはプログラマーの個人的な問題であり、いわばプログラマーの責任である。intからshortへの暗黙の変換などは、言語規格で禁止されていませんよね。 それなのに、なぜ今になって説教をするのでしょうか?

2600の潜在的に問題のある場所、そして財政においても - これは道徳的なものではなく、まさにコード品質の指標なのです。


よし、このバグの一つを見つけたぞ。

というログが出ます。

以前のビルドでは、すべてがうまくいっていました。

はい、このバグはすでに5月4日に(おそらく、A100で)議論され、修正されています。タイプコントロールでやりすぎたらしい。

最新のMetaEditor build 1329を添付しましたが、このエラーは出ていません。ぜひそちらでご確認ください。

MT5の発売は5月12日です。

ファイル:
削除済み  
Alexey Navoykov:

以前のビルドでは問題なかったのですが。

あなたのコードでは、プライベート・オブジェクトへの const-pointerを返していません。プログラマがprivateを指定しているため、サードパーティ(変数の可視性という意味で)の関数が、アーキテクチャ上アクセスできないはずのものを一見して変更できることが判明したのです。

プライベートなオブジェクトへのポインタを返したいときは、必ず const 修飾子を指定します。あなたの場合、私は反りを設定します。

私は高飛車ではないので、質問させていただきました。このコードはどこかで使わないといけないのか、それともconstを設定するのが面倒なのか?

削除済み  
A100:

2日間が実質的に無駄になってしまったので(この歳になるともう大変)、ちょっと違う使い方をしようと思っていたのです。

100以上のバグを挙げましたね。毎回そんな野暮なことを言うのか!?開発者に対するそのような寛容さは、どこから得たのでしょうか?
アレクセイ・ナヴォイコフ

A100さんの忍耐力には改めて脱帽です。 私自身も疲れました。新しいビルドのバグの原因を探し、サービスデスクで作業 するより、問題なく動作する古いビルドに座っている方が楽です。 それとも誰かこの作業に対してお金を払ってくれるのでしょうか

そう、サードパーティのテスターが無償で行うサービスデスクは格好の材料なのです。もちろん、そのために作られたものではありませんが、実際、まさにサードパーティのテスターが無償で働くための雇用主になっています。もし、これらのバグレポートがなかったら、コンパイラのコンパイルにもっと時間がかかっていたことでしょう。

世の中の慣例として、バグを見つけたら報いを受けるべきと誰もが主張するだろう。A100は国家試験官の給料をもらうべき。そして、一見テスターの1年分の給料のように見える。

 
Renat Fatkhullin:

はい、このエラーはすでに(おそらくA100で)議論され、5月4日の時点で修正されています。型式制御をやりすぎたらしい。

このエラーが含まれていない最新のMetaEditor build 1329を添付します。ぜひそちらでご確認ください。

MT5の発売は5月12日です。

確認しました。プログラムとは別に再現できないが、何らかのランダムな方法で回避することができる奇妙な不思議を除いて、今ではほとんどコンパイルエラーはない。

以下は、今回お伝えする問題部分のサンプルコードです。 ここでも、別途コンパイルはうまくいっていますが、私のプログラムではエラーが発生します。

class CBase
{
};


class CClass : public CBase
{
};

 

class CWork
{
 public:
 
  template<typename T>
  void Run(T& arr[])
  {
    struct Struct
    {
      template<typename T1> static void Set(T1& main,  T& arr[], CBase& obj)   { main.Set(arr); } 
    };
    
    Struct structobj;
    
    structobj.Set(this, arr, arr[0]);
  }

  
  template<typename T>
  void Set(T& arr[]) 
  {  
    for (int i=0; i<ArraySize(arr); i++) Set(arr[i]);  // Здесь возникает ошибка: 'arr' - parameter conversion not allowed
  }
  
  template<typename T>
  void Set(T& obj)    { } 
  
  template<typename T>
  void Set(T*& obj)    { } 

};
 
 

void Main()
{
  CWork work;
  CClass arr[];
  work.Run(arr);

  return;
}

Main関数内で任意の場所(例えばreturnの後など)に行を追加した場合。

work.Set(arr[0])。

は正常にコンパイルされます。

プログラマーは最適化をやりすぎたようです。

あと、実行時の不具合もありますね。例えば、ある構造体のメンバに 値を代入したところ、そこの値が古い、つまり何も代入されていないことがわかった。 その近くに任意の操作をした行を追加すると、すべてが正常になる。 これらのバグは、コンパイラを最適化したあの秋のビルドから始まっています。 結局、すべてが生のままなのです。

また、コンパイル自体も、ビルド1159では1〜2秒だったのが、20秒かかるようになりました。 同時に、プログラムの大幅な高速化も感じられず、10〜20%程度の上昇にとどまっています。ですから、2倍から10倍のスピードアップという話は、もう忘れてください。特別に選ばれたテストサンプルではそうなるのかもしれませんが、私たちが持っているのは本物のアプリケーションであって、偽物ではありません。

その結果、10倍から20倍の速度でコンパイルが行われることになります。 プログラマーが失う時間の方がはるかに価値があると思います。

今も1159ビルドのままを余儀なくされています。

 
Anton Zverev:

あなたのコードでは、プライベート・オブジェクトへの const-pointerを返していません。プログラマがprivateを指定しているため、サードパーティ(変数の可視性という意味で)の関数が、アーキテクチャ的にアクセスできないはずのものを一見して変更できることが判明したのです。

プライベートなオブジェクトへのポインタを返したいときは、必ず const 修飾子を指定します。あなたの場合、私は反りを付けますね。

私は高飛車ではないので、質問させていただきました。このコードはどこかで使わないといけないのか、それともconstを設定するのが面倒なのか?

CClassオブジェクト自体はユーザがフルにアクセスできるのに、配列だけprivateに隠す、それが目的です。 読み取りのみに必要なら、constをつけますね。

 
Anton Zverev:
世の中の慣例として、バグを発見したら報復があるべきだというのは、すべての人が支持するでしょう。A100は国家試験官の給料をもらうべき。そして、一見テスターの1年分の給料のように見える。
私はそれを支持しますが、楯と表彰状にとどまるのではないかと思います :)
 

バグなのか、CDealInfoPositionId()とTicket() のメソッドの説明が間違っているだけなのかわかりません。次のようなコードを書きました。

//+------------------------------------------------------------------+
//|                                                      test_01.mq5 |
//|                                                   Sergey Gritsay |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Sergey Gritsay"
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh>
//#include <Trade\DealInfo.mqh>
CTrade trade;
CDealInfo deal;
ulong  ticket_deal;      // тикет сделки
ulong  ticket_position;     // тикет позиции
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   trade.Buy(0.1,_Symbol);
   ticket_deal=trade.ResultDeal();
   deal.Ticket(ticket_deal);
   ticket_position=deal.PositionId();

   Print("ResultDeal() = ",ticket_deal);
   Print("deal.PositionId() = ",ticket_position);
  }
//+------------------------------------------------------------------+

出来栄え

NM      0       14:06:49.083    test_01 (EURUSD,H1)     ResultDeal() = 69380150
QE      0       14:06:49.083    test_01 (EURUSD,H1)     deal.PositionId() = 0

HistorySelect() 関数を使って、案件の履歴のリクエストを追加してみました。

//+------------------------------------------------------------------+
//|                                                      test_01.mq5 |
//|                                                   Sergey Gritsay |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Sergey Gritsay"
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh>
//#include <Trade\DealInfo.mqh>
CTrade trade;
CDealInfo deal;
ulong  ticket_deal;      // тикет сделки
ulong  ticket_position;     // тикет позиции
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   trade.Buy(0.1,_Symbol);
   ticket_deal=trade.ResultDeal();
   HistorySelect(0,TimeCurrent());
   deal.Ticket(ticket_deal);
   ticket_position=deal.PositionId();

   Print("ResultDeal() = ",ticket_deal);
   Print("deal.PositionId() = ",ticket_position);
  }
//+------------------------------------------------------------------+

出来栄え

JM      0       14:16:33.055    test_01 (EURUSD,H1)     ResultDeal() = 69381116
EF      0       14:16:33.055    test_01 (EURUSD,H1)     deal.PositionId() = 83654708
削除済み  
Alexey Navoykov:

配列をprivateで隠すだけで、CClassオブジェクト自体はユーザーがフルアクセスできるようにする、それが目的 です。 読み取り専用にする必要があれば、constをつけますね。

なるほど、どのような構成で使えるのか、教えてください。この方法では、配列自体には何もできない(リサイズ、要素の入れ替えなど)ことは理解しています。を削除することができますが、適用することができます...

異なるオブジェクト型でも[]演算子の構文が同じになるように、どこかでテンプレートでやっているのでしょうね。一般的に、この構成は便利な時に使うということを示してもらえないでしょうか。