Java と C# で off-by-one(ひとつ違い)
Java の printf ですが、C 同様に型安全ではないという検証をしてみました
(試していませんが format も同じだと思います。用途からみて format の方が
問題だと思います)
以下は、% を一個付け忘れてしまったという例です。コンパイル時に誤りを検出
できないため、型安全ではありません
後から設計した言語でありながら、バグを量産する可能性のある特性まで
輸入してしまっているのは何も考えていない証拠でしょう
public class off_by_one {
public static void main(String[] args){
int x = 10;
int y = 20;
int sum = x + y;
System.out.printf("%d + %d = d%n", x, y, sum);
}
}
C:\Projects\workspace\off_by_one>java off_by_one
10 + 20 = d
一応、可変引数の方が少ないと
public class off_by_one {
public static void main(String[] args){
int x = 10;
int y = 20;
int sum = x + y;
System.out.printf("%d + %d = %d%d%n", x, y, sum);
}
}
例外を投げてくれるのですが、コンパイル時に動作を決定できないという点で、
設計上問題のある実装と言えるでしょう。例外を catch するコーディングを
しなくてもコンパイラが指摘しませんから無意味です
C:\Projects\workspace\off_by_one>java off_by_one
10 + 20 = 30Exception in thread "main" java.util.MissingFormatArgumentException: Format specifier 'd'
at java.util.Formatter.format(Unknown Source)
at java.io.PrintStream.format(Unknown Source)
at java.io.PrintStream.printf(Unknown Source)
at off_by_one.main(off_by_one.java:9)
C# でも off-by-one 実験をしました
■ {2} を {1} と入力
・この例では最後の引数が出力されないバグが発生
using System;
namespace off_by_one
{
/// <summary>
/// Class1 の概要の説明です。
/// </summary>
class Class1
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: アプリケーションを開始するコードをここに追加してください。
//
int x = 1;
int y = 2;
int z = x + y;
Console.WriteLine("{0}+{1}={1}", x, y, z);
Console.ReadLine();
}
}
}
■ {2} を {3} と入力
・この例では例外が発生。例外を補足することも強制されない
using System;
namespace off_by_one
{
/// <summary>
/// Class1 の概要の説明です。
/// </summary>
class Class1
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: アプリケーションを開始するコードをここに追加してください。
//
int x = 1;
int y = 2;
int z = x + y;
Console.WriteLine("{0}+{1}={3}", x, y, z);
Console.ReadLine();
}
}
}