Saya telah mempelajari tutorial OpenCV dan menemukan assert
fungsinya; apa fungsinya?
Saya telah mempelajari tutorial OpenCV dan menemukan assert
fungsinya; apa fungsinya?
Jawaban:
assert
akan menghentikan program (biasanya dengan pesan yang mengutip pernyataan tegas) jika argumennya ternyata salah. Ini biasa digunakan selama debugging untuk membuat program gagal lebih jelas jika kondisi yang tidak terduga terjadi.
Sebagai contoh:
assert(length >= 0); // die if length is negative.
Anda juga dapat menambahkan pesan yang lebih informatif untuk ditampilkan jika gagal seperti:
assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");
Atau yang lain seperti ini:
assert(("Length can't possibly be negative! Tell jsmith", length >= 0));
Saat Anda melakukan rilis (non-debug) build, Anda juga dapat menghapus overhead evaluasi assert
pernyataan pernyataan dengan mendefinisikan NDEBUG
makro, biasanya dengan saklar kompiler. Akibat dari hal ini adalah bahwa program Anda seharusnya tidak pernah mengandalkan menjalankan makro yang tegas.
// BAD
assert(x++);
// GOOD
assert(x);
x++;
// Watch out! Depends on the function:
assert(foo());
// Here's a safer way:
int ret = foo();
assert(ret);
Dari kombinasi panggilan program batal () dan tidak dijamin untuk melakukan apa pun, pernyataan hanya boleh digunakan untuk menguji hal-hal yang diasumsikan oleh pengembang alih-alih, misalnya, pengguna memasukkan angka daripada huruf (yang seharusnya ditangani dengan cara lain).
assert
Biasanya memunculkan eksepsi" - dalam C ++ tidak muncul "eksepsi" yang disebutnya batal ... sedikit berbeda.
#
karakter tidak memperkenalkan komentar.
assert("error message", expression)
The menegaskan pernyataan komputer analog dengan pernyataan make yakin dalam bahasa Inggris.
Melihat
assert () contoh program dalam C ++
Banyak kompiler menawarkan makro assert (). Makro assert () mengembalikan TRUE jika parameternya mengevaluasi TRUE dan mengambil beberapa tindakan jika mengevaluasi FALSE. Banyak kompiler akan membatalkan program pada assert () yang gagal; yang lain akan melemparkan pengecualian
Salah satu fitur kuat dari makro assert () adalah bahwa preprocessor menciutkannya menjadi tidak ada kode sama sekali jika DEBUG tidak didefinisikan. Ini sangat membantu selama pengembangan, dan ketika produk akhir dikirimkan tidak ada penalti kinerja atau peningkatan ukuran versi program yang dapat dieksekusi.
Misalnya
#include <stdio.h>
#include <assert.h>
void analyze (char *, int);
int main(void)
{
char *string = "ABC";
int length = 3;
analyze(string, length);
printf("The string %s is not null or empty, "
"and has length %d \n", string, length);
}
void analyze(char *string, int length)
{
assert(string != NULL); /* cannot be NULL */
assert(*string != '\0'); /* cannot be empty */
assert(length > 0); /* must be positive */
}
/**************** Output should be similar to ******************
The string ABC is not null or empty, and has length 3
Fungsi assert () dapat mendiagnosis bug program. Dalam C, didefinisikan dalam <assert.h>
, dan dalam C ++ itu didefinisikan dalam <cassert>
. Prototipenya adalah
void assert(int expression);
Ekspresi argumen dapat berupa apa pun yang ingin Anda uji - variabel atau ekspresi C apa pun. Jika ekspresi bernilai TRUE, menegaskan () tidak melakukan apa-apa. Jika ekspresi mengevaluasi ke FALSE, menegaskan () menampilkan pesan kesalahan pada stderr dan membatalkan eksekusi program.
Bagaimana Anda menggunakan menegaskan ()?Ini paling sering digunakan untuk melacak bug program (yang berbeda dari kesalahan kompilasi). Bug tidak mencegah program untuk dikompilasi, tetapi menyebabkannya untuk memberikan hasil yang salah atau berjalan dengan tidak benar (misalnya, mengunci). Misalnya, program analisis keuangan yang Anda tulis terkadang memberikan jawaban yang salah. Anda mencurigai bahwa masalah disebabkan oleh variabel interest_rate mengambil nilai negatif, yang seharusnya tidak pernah terjadi. Untuk memeriksa ini, tempatkan pernyataan
menegaskan (interest_rate> = 0); di lokasi dalam program di mana interest_rate digunakan. Jika variabel pernah menjadi negatif, makro assert () memberi tahu Anda. Anda kemudian dapat memeriksa kode yang relevan untuk menemukan penyebab masalah.
Untuk melihat cara kerja assert (), jalankan contoh program di bawah ini . Jika Anda memasukkan nilai bukan nol, program menampilkan nilai dan berakhir secara normal. Jika Anda memasukkan nol, makro pernyataan () memaksa penghentian program tidak normal. Pesan kesalahan persis yang Anda lihat akan tergantung pada kompiler Anda, tetapi inilah contoh khasnya:
Pernyataan gagal: x, file list19_3.c, baris 13 Perhatikan bahwa, agar assert () berfungsi, program Anda harus dikompilasi dalam mode debug. Lihat dokumentasi kompiler Anda untuk informasi tentang mengaktifkan mode debug (seperti dijelaskan sebentar lagi). Saat nanti Anda mengkompilasi versi final dalam mode rilis, makro assert () dinonaktifkan.
int x;
printf("\nEnter an integer value: ");
scanf("%d", &x);
assert(x >= 0);
printf("You entered %d.\n", x);
return(0);
Masukkan nilai integer: 10
Anda memasukkan 10.
Masukkan nilai integer: -1
Pesan Kesalahan: Penghentian program yang tidak normal
Pesan kesalahan Anda mungkin berbeda, tergantung pada sistem dan kompiler Anda, tetapi gagasan umumnya sama.
Hal-hal seperti 'menimbulkan pengecualian' dan 'menghentikan eksekusi' mungkin benar untuk sebagian besar kompiler, tetapi tidak untuk semua. (BTW, apakah ada pernyataan tegas yang benar-benar memberikan pengecualian?)
Berikut adalah makna asersi yang menarik, sedikit berbeda yang digunakan oleh c6x dan kompiler TI lainnya: setelah melihat pernyataan tegas tertentu, kompiler ini menggunakan informasi dalam pernyataan itu untuk melakukan optimasi tertentu. Jahat.
Contoh dalam C:
int dot_product(short *x, short *y, short z)
{
int sum = 0
int i;
assert( ( (int)(x) & 0x3 ) == 0 );
assert( ( (int)(y) & 0x3 ) == 0 );
for( i = 0 ; i < z ; ++i )
sum += x[ i ] * y[ i ];
return sum;
}
Ini memberitahu de compiler bahwa array disejajarkan pada batas 32-bit, sehingga kompiler dapat menghasilkan instruksi spesifik yang dibuat untuk perataan semacam itu.
C ++ 11 N3337 konsep standar
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
19.3 Penegasan
1 Header <cassert>, dijelaskan dalam (Tabel 42), menyediakan makro untuk mendokumentasikan pernyataan program C ++ dan mekanisme untuk menonaktifkan pemeriksaan pernyataan.
2 Isi sama dengan tajuk pustaka C Standar <assert.h>.
C99 N1256 draft standar
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
7.2 Diagnostik <assert.h>
1 Header
<assert.h>
mendefinisikan makro pernyataan dan merujuk ke makro lain,NDEBUG
yang tidak didefinisikan oleh<assert.h>
. JikaNDEBUG
didefinisikan sebagai nama makro pada titik di file sumber di mana <assert.h> disertakan, makro pernyataan didefinisikan hanya sebagai#define assert(ignore) ((void)0)
Makro menegaskan didefinisikan ulang sesuai dengan keadaan saat ini NDEBUG setiap kali
<assert.h>
disertakan.2. Makro menegaskan harus diimplementasikan sebagai makro, bukan sebagai fungsi yang sebenarnya. Jika definisi makro ditekan untuk mengakses fungsi aktual, perilaku tidak terdefinisi.
7.2.1 Diagnostik program
7.2.1.1 Makro tegas
Ringkasan
1.
#include <assert.h> void assert(scalar expression);
Deskripsi
2 Makro menegaskan menempatkan tes diagnostik ke dalam program; itu mengembang ke ekspresi kosong. Ketika dieksekusi, jika ekspresi (yang akan memiliki tipe skalar) salah (yaitu, sama dengan 0), makro menegaskan menulis informasi tentang panggilan tertentu yang gagal (termasuk teks argumen, nama file sumber, nomor baris sumber, dan nama fungsi melampirkan - yang terakhir masing-masing adalah nilai-nilai makro preprocessing
__FILE__
dan__LINE__
dan pengidentifikasi__func__
) pada aliran kesalahan standar dalam format yang ditentukan implementasi. 165) Ini kemudian memanggil fungsi batal.Kembali
3 Makro menegaskan tidak mengembalikan nilai.
Ada tiga alasan utama untuk menggunakan fungsi assert () di atas normal jika lain dan printf
Fungsi assert () terutama digunakan dalam fase debugging, itu membosankan untuk menulis jika lagi dengan pernyataan printf setiap kali Anda ingin menguji suatu kondisi yang bahkan mungkin tidak membuat jalannya dalam kode akhir.
Dalam penyebaran perangkat lunak besar, pernyataan menjadi sangat berguna di mana Anda dapat membuat kompilator mengabaikan pernyataan pernyataan menggunakan makro NDEBUG yang ditentukan sebelum menautkan file header untuk fungsi assert ().
assert () berguna ketika Anda sedang merancang suatu fungsi atau beberapa kode dan ingin mendapatkan ide tentang apa yang membatasi kode akan dan tidak bekerja dan akhirnya menyertakan jika ada untuk mengevaluasi itu pada dasarnya bermain dengan asumsi.
Ini adalah fungsi yang akan menghentikan eksekusi program jika nilai yang dievaluasi salah. Biasanya dikelilingi oleh makro sehingga tidak dikompilasi ke dalam biner yang dihasilkan ketika dikompilasi dengan pengaturan rilis.
Ini dirancang untuk digunakan untuk menguji asumsi yang telah Anda buat. Sebagai contoh:
void strcpy(char* dest, char* src){
//pointers shouldn't be null
assert(dest!=null);
assert(src!=null);
//copy string
while(*dest++ = *src++);
}
Yang ideal yang Anda inginkan adalah bahwa Anda dapat membuat kesalahan dalam program Anda, seperti memanggil fungsi dengan argumen yang tidak valid, dan Anda menekan sebuah pernyataan sebelum segfaults (atau gagal berfungsi seperti yang diharapkan)
Selain itu, Anda dapat menggunakannya untuk memeriksa apakah alokasi dinamis berhasil.
Contoh kode:
int ** p;
p = new int * [5]; // Dynamic array (size 5) of pointers to int
for (int i = 0; i < 5; ++i) {
p[i] = new int[3]; // Each i(ptr) is now pointing to a dynamic
// array (size 3) of actual int values
}
assert (p); // Check the dynamic allocation.
Mirip dengan:
if (p == NULL) {
cout << "dynamic allocation failed" << endl;
exit(1);
}
new
Melempar pengecualian pada kegagalan alokasi kecuali Anda menentukan nothrow
(yang tidak Anda lakukan di sini). Selain itu, format Anda aneh dan exit
jahat.
assert()
hanya untuk debugging dan menghilangkan hal-hal yang seharusnya tidak pernah terjadi - jauh sebelum rilis rilis dibuat.