
Review kode pasti dibutuhkan dan berguna. Ini adalah kesempatan untuk mentransfer pengetahuan, pelatihan, kontrol atas tugas, meningkatkan kualitas dan desain kode, dan memperbaiki kesalahan. Selain itu, Anda dapat melihat kesalahan tingkat tinggi yang terkait dengan arsitektur dan algoritme yang digunakan. Secara umum, semuanya baik-baik saja, tetapi orang cepat lelah. Oleh karena itu, analisis statis adalah suplemen yang sangat baik untuk ulasan dan membantu mengidentifikasi berbagai kesalahan dan kesalahan cetak yang tidak terlihat oleh mata. Mari kita lihat contoh yang bagus tentang topik ini.
Cobalah untuk menemukan kesalahan dalam kode fungsi yang diambil dari pustaka structopt :
static inline bool is_valid_number(const std::string &input) {
if (is_binary_notation(input) ||
is_hex_notation(input) ||
is_octal_notation(input)) {
return true;
}
if (input.empty()) {
return false;
}
std::size_t i = 0, j = input.length() - 1;
// Handling whitespaces
while (i < input.length() && input[i] == ' ')
i++;
while (input[j] == ' ')
j--;
if (i > j)
return false;
// if string is of length 1 and the only
// character is not a digit
if (i == j && !(input[i] >= '0' && input[i] <= '9'))
return false;
// If the 1st char is not '+', '-', '.' or digit
if (input[i] != '.' && input[i] != '+' && input[i] != '-' &&
!(input[i] >= '0' && input[i] <= '9'))
return false;
// To check if a '.' or 'e' is found in given
// string. We use this flag to make sure that
// either of them appear only once.
bool dot_or_exp = false;
for (; i <= j; i++) {
// If any of the char does not belong to
// {digit, +, -, ., e}
if (input[i] != 'e' && input[i] != '.' &&
input[i] != '+' && input[i] != '-' &&
!(input[i] >= '0' && input[i] <= '9'))
return false;
if (input[i] == '.') {
// checks if the char 'e' has already
// occurred before '.' If yes, return false;.
if (dot_or_exp == true)
return false;
// If '.' is the last character.
if (i + 1 > input.length())
return false;
// if '.' is not followed by a digit.
if (!(input[i + 1] >= '0' && input[i + 1] <= '9'))
return false;
}
else if (input[i] == 'e') {
// set dot_or_exp = 1 when e is encountered.
dot_or_exp = true;
// if there is no digit before 'e'.
if (!(input[i - 1] >= '0' && input[i - 1] <= '9'))
return false;
// If 'e' is the last Character
if (i + 1 > input.length())
return false;
// if e is not followed either by
// '+', '-' or a digit
if (input[i + 1] != '+' && input[i + 1] != '-' &&
(input[i + 1] >= '0' && input[i] <= '9'))
return false;
}
}
/* If the string skips all above cases, then
it is numeric*/
return true;
}
Agar tidak langsung membaca jawabannya secara tidak sengaja, saya akan menambahkan gambar.

Saya tidak tahu apakah Anda menemukan kesalahan atau tidak. Bahkan jika Anda sudah menemukannya, Anda pasti akan setuju bahwa tidak mudah menemukan kesalahan ketik seperti itu. Selain itu, Anda tahu bahwa ada kesalahan dalam fungsi tersebut. Jika Anda tidak tahu, maka sulit untuk membuat Anda membaca dan memeriksa semua kode ini dengan cermat.
Dalam situasi seperti itu, penganalisis kode statis akan melengkapi tinjauan kode klasik dengan sempurna. Penganalisis tidak akan lelah dan akan memeriksa seluruh kode secara menyeluruh. Akibatnya, penganalisis PVS-Studio melihat adanya anomali dalam fungsi ini dan mengeluarkan peringatan:
V560 Bagian dari ekspresi bersyarat selalu salah: input [i] <= '9'. structopt.hpp 1870
Bagi yang tidak memperhatikan error tersebut, saya akan memberikan penjelasannya. Hal yang paling penting:
else if (input[i] == 'e') {
....
if (input[i + 1] != '+' && input[i + 1] != '-' &&
(input[i + 1] >= '0' && input[i] <= '9'))
return false;
}
Kondisi di atas memeriksa bahwa elemen ke-i adalah huruf 'e'. Karenanya, input cek berikut [i] <= '9' tidak masuk akal. Hasil pemeriksaan kedua selalu salah, itulah yang diperingatkan oleh alat analisis statis. Alasan kesalahannya sederhana: orang tersebut bergegas dan menyegel dirinya sendiri, lupa menulis +1.
Faktanya, ternyata fungsinya tidak menyelesaikan tugasnya untuk memeriksa kebenaran angka yang dimasukkan. Opsi yang benar:
else if (input[i] == 'e') {
....
if (input[i + 1] != '+' && input[i + 1] != '-' &&
(input[i + 1] >= '0' && input[i + 1] <= '9'))
return false;
}
Pengamatan yang menarik. Kesalahan ini dapat dilihat sebagai variasi dari " efek baris terakhir ". Kesalahan terjadi di kondisi terakhir dari fungsi tersebut. Pada akhirnya, perhatian programmer memudar, dan dia membuat kesalahan kecil ini.

Jika Anda menyukai artikel tentang efek baris terakhir, maka saya sarankan membaca pengamatan serupa lainnya: 0-1-2 , memset , perbandingan .
Selamat tinggal semuanya. Saya suka mereka yang menemukan kesalahannya sendiri.