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

 
Yedelkin:

では、原則的に2つの値しか持たないbool型の 変数にdefault:return(false )を指定する意味は何でしょうか。つまり、デフォルトのラベルは一切実行してはいけないのです。

P.S. 1.また、あなたのアプローチに従えば、デフォルトのラベルはオプションではなく、必須になります。

2.ブレーク演算子はどちらの場合も意味がない。

switch 演算子は、bool_varを 整数型に変換します。

そして、コンパイラはこの変数が2つの値を持つことを知る必要はないのです。アルゴリズムを論理的に解析していないのです。

 
Interesting:

もうひとつ忘れていることがある。どんな変数でも、無効な値を持ったり、初期化されていない(「ゴミ」のような値を持っている)ことがある......。

忘れない。つまり、私の例では変数が初期化されたのです。にもかかわらず、コンパイラはエラーを発生させた。

bool_var=- 1の例は、極めて不正確 です。ご自身の目でお確かめください。

bool bool_var=-1;
void OnStart()
  {
   Print("bool_var=",bool_var);
  }   
 
Dima_S:

switch 文は、bool_varを 整数型に 変換します。

そして、コンパイラはこの変数が二つの値を持っていることを知る必要はない。アルゴリズムを論理的に解析していないのです。

ところで、ブーリアンでは、例えば初期化されていない変数や値-1の変数がtrue/falseにキャストされる場合、ラッキーバリアントが存在します。

もちろん、変数を明示的にintと宣言した場合には、このようなことは起こりません。

イェデルキン

忘れない。そのため、私の例では変数が初期化されました。にもかかわらず、コンパイラはエラーを発生させた。

bool_var=- 1の例は、極めて不正確 です。自分を納得させる。

もう納得しているからこそ、削除したんです。しかし、それは偶然の幸運なのです(言語の特徴として考えてください)。

しかし、スイッチ ブロックの中で起こりうるエラーを処理する場合、コンパイラはそこに何がどのように入力されているかを把握する必要がないため、警告ではなくエラーとして扱われるのです。

 
Dima_S:

そして、コンパイラはこの変数が二つの値を持っていることを知る必要はない。アルゴリズムの論理的な解析をしているわけではないのです。

つまり、コンパイラは列挙された値のリストとその総数を考慮しないと言うことですか?

 
Interesting:

しかし、スイッチ ブロックの中でエラーの可能性がある処理をする場合、コンパイラは何がどのように入力されているかを把握する必要がないため、警告ではなく、エラーとして処理します。

中間的な結論としては、列挙+スイッチの場合、デフォルトラベルの使用が必須と なる、ということです。
 
Yedelkin:

1. boolはすでに「整数型」である。それともswitchは上位の整数型への変換ということなのでしょうか。

2.コンパイラはenum値のリストとその総数を考慮していないということでしょうか?

1. boolは1バイトの整数型である。変換先はint型、おっしゃる通りです。

2.こちらも正解です。caseのみは列挙ではなく、条件分岐のためのラベルに過ぎない。

Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
  • www.mql5.com
Основы языка / Типы данных / Целые типы / Типы char, short, int и long - Документация по MQL5
 
Dima_S:

1. boolは1バイトの整数型です。変換がint型に なるのは、その通りです。

Handbookによると、boolはinteger以外の特殊な型だそうです...。そこで、誤った記述を削除しました。反論はしませんが......私は専門家ではありません。

Dima_S です。

イェデルキン

つまり、コンパイラは列挙された値のリストとその総数を考慮しないということですか?

2.こちらもちゃんと書いてくれていますね。caseのみは列挙ではなく、条件分岐のラベルに過ぎない。

ケースラベルではなく、列挙型(bool型を最小と考える)のことです。以下は、同じコンパイルエラーの例です。

enum Triple
  {
   err=-1,
   no = 0,
   hay= 1
  };
Triple triple_var=err;
Triple Test(void)
  {
   switch(triple_var)
     {
      case  err: return(err);
      case   no: return(no);
      case  hay: return(hay);
      //default:return(hay);
     }
  }
void OnStart()
  {
   Test();
  }

この例に関する質問を繰り返しますが、コンパイラはTriple列挙型の値のリストとその総数を考慮しないということですか? 私はすべての列挙型の値をswitch演算子で使用しています。

 
Yedelkin:
中間的な結論としては、enumeration+switchを使用する場合、デフォルトラベルの使用が必須と なる、ということでしょうか。

このように想像してみよう(ちなみに、値3は明示的に宣言しても動作しないが、-1なら簡単に動作する)。しかし、明示的な変数の初期 化がなければ、インデックスが0のものと同じ値であることがわかります(ここはすべてよく考えられています)。

デフォルトのオプションを除外した場合、この関数は何を返すべきでしょうか?

ENUM_CHART_MODE ChartMode = -1;

string Test()
  {
   switch(ChartMode)
     {
      case 0: return("Bars"); break;
      case 1: return("CANDLES"); break;
      case 2: return("LINE"); break;      
      default: return("Unknown");
     }
  }
void OnStart()
{
Comment(Test());
}
 
Yedelkin:
中間的な結論としては、enumeration+switchを使用する場合、デフォルトラベルの使用が必須と なる、ということでしょうか。

はい、return()で何かを返す必要がある場合です。

あるいは、少なくともコンパイラがその関数が何かを返すことを確認できるようにします。

bool bool_var=false;
bool Test(void)
  {
   switch(bool_var)
     {
      case  true: return(true);
      case false: return(false);
     }
    return(false);//хотя до сюда ни когда не дойдем, но прописать надо
  }
void OnStart()
  {
   Test();
  }
 
皆さん、サイエンスありがとうございました余分な行を入れるために歯を食いしばることになる :)