Peretasan yang saya lihat di sekitar adalah menggunakan &&operator. Karena pointer "benar" jika bukan nol, Anda dapat melakukan hal berikut tanpa mengubah kondisinya:
assert(a == b &&"A is not equal to B");
Karena assertmenunjukkan kondisi yang gagal, itu akan menampilkan pesan Anda juga. Jika itu tidak cukup, Anda dapat menulis myAssertfungsi atau makro Anda sendiri yang akan menampilkan apa pun yang Anda inginkan.
Pilihan lain adalah membalikkan operan dan menggunakan operator koma. Anda membutuhkan tanda kurung tambahan sehingga koma tidak diperlakukan sebagai pembatas di antara argumen:assert(("A must be equal to B", a == b));
Keith Thompson
3
Akan lebih baik, meskipun, untuk dapat mencetak nilai-nilai variabel, seperti pada:assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
Frank
7
@ Sejujurnya, printfmengembalikan nilai bukan nol jika itu mencetak sesuatu, sehingga Anda bisa melakukan sesuatu seperti assert(a == b && printf("a (%i) is not equal to b (%i)", a, b)), meskipun pada saat itu Anda mungkin harus menulis pembungkus tegas Anda sendiri.
zneak
1
Kode yang salah! Saya tidak mengerti ini! Jika a == b salah, ekspresi-dan juga harus salah, dan, oleh karena itu, string tidak boleh dievaluasi.
ragnarius
1
@ TUIlover, bukan itu cara kerja string C literal; mereka adalah konstanta waktu kompilasi dan penggunaannya dalam konteks ini secara sepele dioptimalkan. Tidak ada biaya runtime.
zneak
45
Pilihan lain adalah membalikkan operan dan menggunakan operator koma. Anda membutuhkan tanda kurung tambahan sehingga koma tidak diperlakukan sebagai pembatas di antara argumen:
assert(("A must be equal to B", a == b));
(ini disalin dari komentar di atas, untuk visibilitas yang lebih baik)
Ini adalah pendekatan yang hebat, dengan satu masalah kecil, ini akan menampilkan "peringatan: operan kiri dari operator koma tidak berpengaruh" ketika dikompilasi dalam g ++ dengan `-Wunused-value
v010dya
1
atau dengan makro: #ifndef m_assert #define m_assert (expr, msg) menegaskan ((msg, expr)) #endif
Szymon Marczak
Menggunakan pembungkus makro memungkinkan Anda menghindari peringatan gcc:#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Jander
25
Inilah versi makro pernyataan saya, yang menerima pesan dan mencetak semuanya dengan jelas:
Saya agak bingung. Apakah #Expr diperlakukan sebagai string untuk substitusi langsung? Apa perbedaan antara #Expr dan Expr?
Minh Tran
@ MinhTran Mari kita asumsikan bahwa kondisi tegas Anda x == y. Kemudian Expr akan diperluas ke if( !(x == y))dan di sinilah kondisinya diperiksa, dan #Expr akan diperluas ke string literal "x == y", yang kemudian kita masukkan ke dalam pesan kesalahan.
Eugene Magdalits
Sayangnya, solusi ini menyebabkan perilaku tidak terdefinisi karena menggunakan pengidentifikasi yang dicadangkan.
Anda dapat menggunakannya secara langsung atau menyalin kode Boost. Perhatikan juga Boost assert hanya header, jadi Anda bisa mengambil file tunggal itu jika Anda tidak ingin menginstal semua Boost.
@Jichao, apa maksudmu dengan mengimplementasikan antarmuka tegas?
Tarc
7
Karena jawaban zneak agak rumit dalam kode, pendekatan yang lebih baik adalah dengan hanya mengomentari teks string yang sedang Anda bicarakan. yaitu.:
assert(a == b);// A must be equal to B
Karena pembaca kesalahan tegas akan mencari file dan baris pula dari pesan kesalahan, mereka akan melihat penjelasan lengkap di sini.
Karena, pada akhirnya, ini:
assert(number_of_frames !=0);// Has frames to update
membaca lebih baik dari ini:
assert(number_of_frames !=0&&"Has frames to update");
dalam hal penguraian kode manusia yaitu. keterbacaan. Juga bukan peretasan bahasa.
"Karena pembaca kesalahan tegas akan mencari file dan baris pula dari pesan kesalahan," - hanya jika mereka rajin.
Jason S
Hanya jika mereka ingin memperbaiki bug yang Anda maksud ... komentar yang konyol
metamorfosis
1
Tidak. Semakin mudah Anda membuat orang melihat masalahnya, semakin besar kemungkinan mereka akan mengambil tindakan.
Jason S
mengangkat bahu Tidak setuju.
metamorfosis
2
assert adalah kombinasi makro / fungsi. Anda dapat menentukan makro Anda sendiri / fungsi, menggunakan __FILE__, __BASE_FILE__, __LINE__dll, dengan fungsi sendiri yang mengambil pesan khusus
Jawaban:
Peretasan yang saya lihat di sekitar adalah menggunakan
&&
operator. Karena pointer "benar" jika bukan nol, Anda dapat melakukan hal berikut tanpa mengubah kondisinya:Karena
assert
menunjukkan kondisi yang gagal, itu akan menampilkan pesan Anda juga. Jika itu tidak cukup, Anda dapat menulismyAssert
fungsi atau makro Anda sendiri yang akan menampilkan apa pun yang Anda inginkan.sumber
assert(("A must be equal to B", a == b));
assert(a == b && "A (" << A << ") is not equal to B (" << B << ")");
printf
mengembalikan nilai bukan nol jika itu mencetak sesuatu, sehingga Anda bisa melakukan sesuatu sepertiassert(a == b && printf("a (%i) is not equal to b (%i)", a, b))
, meskipun pada saat itu Anda mungkin harus menulis pembungkus tegas Anda sendiri.Pilihan lain adalah membalikkan operan dan menggunakan operator koma. Anda membutuhkan tanda kurung tambahan sehingga koma tidak diperlakukan sebagai pembatas di antara argumen:
(ini disalin dari komentar di atas, untuk visibilitas yang lebih baik)
sumber
#define m_assert(expr, msg) assert(( (void)(msg), (expr) ))
Inilah versi makro pernyataan saya, yang menerima pesan dan mencetak semuanya dengan jelas:
Sekarang, Anda bisa menggunakan ini
Dan jika terjadi kegagalan Anda akan mendapatkan pesan seperti ini:
Bagus dan bersih, jangan ragu untuk menggunakannya dalam kode Anda =)
sumber
x == y
. Kemudian Expr akan diperluas keif( !(x == y))
dan di sinilah kondisinya diperiksa, dan #Expr akan diperluas ke string literal"x == y"
, yang kemudian kita masukkan ke dalam pesan kesalahan.http://www.boost.org/doc/libs/1_51_0/libs/utility/assert.html
Anda dapat menggunakannya secara langsung atau menyalin kode Boost. Perhatikan juga Boost assert hanya header, jadi Anda bisa mengambil file tunggal itu jika Anda tidak ingin menginstal semua Boost.
sumber
Karena jawaban zneak agak rumit dalam kode, pendekatan yang lebih baik adalah dengan hanya mengomentari teks string yang sedang Anda bicarakan. yaitu.:
Karena pembaca kesalahan tegas akan mencari file dan baris pula dari pesan kesalahan, mereka akan melihat penjelasan lengkap di sini.
Karena, pada akhirnya, ini:
membaca lebih baik dari ini:
dalam hal penguraian kode manusia yaitu. keterbacaan. Juga bukan peretasan bahasa.
sumber
assert adalah kombinasi makro / fungsi. Anda dapat menentukan makro Anda sendiri / fungsi, menggunakan
__FILE__
,__BASE_FILE__
,__LINE__
dll, dengan fungsi sendiri yang mengambil pesan khusussumber
Untuk vc, tambahkan kode berikut di assert.h,
sumber