Pertanyaan Apakah Kode Pemeriksa statis harus dapat memeriksa batas aritmetika?


(Juga diposting di forum MSDN - Tapi itu tidak mendapatkan banyak lalu lintas, sejauh yang saya bisa lihat.)

Saya sudah mencoba memberikan contoh Assert dan Assume. Ini kode yang saya punya:

public static int RollDice(Random rng)
{
    Contract.Ensures(Contract.Result<int>() >= 2 &&
                     Contract.Result<int>() <= 12);

    if (rng == null)
    {
        rng = new Random();
    }
    Contract.Assert(rng != null);

    int firstRoll = rng.Next(1, 7);
    Contract.Assume(firstRoll >= 1 && firstRoll <= 6);

    int secondRoll = rng.Next(1, 7);
    Contract.Assume(secondRoll >= 1 && secondRoll <= 6);

    return firstRoll + secondRoll;
}

(Bisnis tentang kemampuan menyampaikan referensi nol, bukan yang ada Random referensi adalah murni pedagogis, tentu saja.)

Saya berharap jika pemeriksa tahu itu firstRoll dan secondRoll masing-masing dalam kisaran [1, 6], akan bisa mengetahui bahwa jumlahnya ada di kisaran [2, 12].

Apakah ini harapan yang tidak masuk akal? Saya menyadari ini adalah bisnis yang rumit, mengerjakan apa yang mungkin terjadi ... tapi saya berharap pemeriksa itu cukup pintar :)

Jika ini tidak didukung sekarang, apakah ada orang di sini yang tahu apakah itu mungkin didukung di masa depan yang dekat?

EDIT: Saya sekarang telah menemukan bahwa ada pilihan yang sangat rumit untuk aritmatika dalam pemeriksa statis. Menggunakan kotak teks "lanjutan" saya dapat mencobanya dari Visual Studio, tetapi tidak ada penjelasan yang layak tentang apa yang mereka lakukan, sejauh yang saya tahu.


32
2017-08-07 11:38


asal


Jawaban:


Saya punya jawaban di forum MSDN. Ternyata saya hampir di sana. Pada dasarnya pemeriksa statis bekerja lebih baik jika Anda membagi kontrak "dan-ed". Jadi, jika kita mengubah kode menjadi ini:

public static int RollDice(Random rng)
{
    Contract.Ensures(Contract.Result<int>() >= 2);
    Contract.Ensures(Contract.Result<int>() <= 12);

    if (rng == null)
    {
        rng = new Random();
    }
    Contract.Assert(rng != null);

    int firstRoll = rng.Next(1, 7);
    Contract.Assume(firstRoll >= 1);
    Contract.Assume(firstRoll <= 6);
    int secondRoll = rng.Next(1, 7);
    Contract.Assume(secondRoll >= 1);
    Contract.Assume(secondRoll <= 6);

    return firstRoll + secondRoll;
}

Itu bekerja tanpa masalah. Ini juga berarti contohnya bahkan lebih bermanfaat, karena ini menyoroti poin utama pemeriksa tidak bekerja lebih baik dengan memisahkan kontrak.


14
2017-08-07 20:27



Saya tidak tahu tentang alat MS Contracts Checker, tetapi rentang analisis adalah teknik analisis statis standar; itu secara luas digunakan dalam alat analisis statis komersial untuk memverifikasi bahwa ekspresi subscript adalah legal.

MS Research memiliki rekam jejak yang bagus dalam analisis statis semacam ini, dan saya berharap untuk melakukan analisis rentang semacam itu menjadi tujuan Pemeriksa Kontrak, bahkan jika tidak diperiksa saat ini.


1
2017-08-07 14:10