2020年09月10日
川俣晶の縁側ソフトウェアC# コーディング How To total 837 count

【入門級】byte型の加算がコンパイル・エラーになるケースがある!?

Written By: 川俣 晶連絡先

byte型の足し算ができない!? §

 byte a = 1;は問題ありません。

 byte b = a;も問題ありません。byte a = 1;の次に宣言しているとすればです。

 byte c = a+1;は問題あります。コンパイラがエラーになります。不思議ですね。エラーの内容は【型 'int' を 'byte' に暗黙的に変換できません。明示的な変換が存在します(cast が不足していないかどうかを確認してください)】です。1はint型の定数なので、これにキャストを付ければ良いのかと思って、(byte)1と書いてみます。

 byte d = a+(byte)1;としてもエラーは同じです。変ですね。aも(byte)1もbyte型です。byte型だけを足しているのになぜエラーになるのでしょうか?

 これは普通の代入文の計算式でやっても同じ結果になります。

 a = a + 1はエラーになります。(もちろんaはbyte型として)

 a = a + (byte)1;もエラーになります。

 なぜこうなるのでしょう。

 それは足し算の+などの演算を行った結果は最低でも32bitの幅のある型になるというC#の言語仕様による振る舞いです。

 つまり計算結果をbyte型の変数に代入する時には常に型を変換しなければなりません。これは32bitよりも狭い全ての型(shortなど)に適用される注意事項です。

 ですから、byte e = (byte)(a+1);のようにキャストを付ければ解決です。

罠の数々 §

  • aがbyte型だとしてa = a +1:はエラーになる。しかし、a += 1;はエラーにならない。a += 1はa = a +1:の省略形ではなく別の機能であることに注意しよう。この振る舞いは似たような言語仕様を持つ他の言語(C言語など)でも同じではないことに注意。C#は出自が違うのである。
  • 普段、int型を使っていると気付きにくい問題であることに注意。逆にいえば、特にメモリを節約する必然性がない場合はint型を使っておくと問題が起きにくい。
  • longなどの32bitよりも大きい型を使っている場合も問題は起きない。計算処理の制約は少なくとも32bitの型になるだけであって、より大きな型には追従してくれる

参考リンク §

算術演算子 (C# リファレンス)

 演算子の制限事項は他にもあります。上記リンクでチェックしてみましょう。

リポジトリ §

https://github.com/autumn009/cshowto

CalcMystery §

using System;

class Program

{

    static void Main()

    {

        byte a = 1; // OK

        byte b = a; // OK

        //byte c = a+1; //  // エラー CS0266  型 'int' を 'byte' に暗黙的に変換できません。明示的な変換が存在します(cast が不足していないかどうかを確認してください)

        //byte d = a+(byte)1; // cast付けてもエラーになる!

        byte e = (byte)(a+1); // OK

        a = b; // OK

        a += 1; // OK

        //a = a + 1;  // エラー CS0266  型 'int' を 'byte' に暗黙的に変換できません。明示的な変換が存在します(cast が不足していないかどうかを確認してください)

        //a = a + (byte)1;    // cast付けてもエラーになる!

        a = (byte)(a + 1);

        Console.WriteLine($"a+b+e={a+b+e}");

    }

}

実行結果

a+b+e=6

COOL C# CREW

C#ハウツー連載の解説増量、カラーのソース、新規書き下ろし追加の読みやすい単行本はこちら。

C#ハウツー: 逆引き入門・こんな機能はどう書くの?