Tôi đã nghiên cứu các hướng dẫn về OpenCV và tìm thấy assert
chức năng này; nó làm gì?
Tôi đã nghiên cứu các hướng dẫn về OpenCV và tìm thấy assert
chức năng này; nó làm gì?
Câu trả lời:
assert
sẽ chấm dứt chương trình (thường là với một thông báo trích dẫn câu lệnh khẳng định) nếu đối số của nó hóa ra là sai. Nó thường được sử dụng trong quá trình gỡ lỗi để làm cho chương trình thất bại rõ ràng hơn nếu xảy ra tình trạng không mong muốn.
Ví dụ:
assert(length >= 0); // die if length is negative.
Bạn cũng có thể thêm một thông báo nhiều thông tin hơn sẽ được hiển thị nếu thất bại như vậy:
assert(length >= 0 && "Whoops, length can't possibly be negative! (didn't we just check 10 lines ago?) Tell jsmith");
Hoặc nếu không như thế này:
assert(("Length can't possibly be negative! Tell jsmith", length >= 0));
Khi bạn đang thực hiện bản dựng phát hành (không gỡ lỗi), bạn cũng có thể loại bỏ chi phí đánh giá các assert
câu lệnh bằng cách xác định NDEBUG
macro, thường là bằng một trình chuyển đổi trình biên dịch. Hệ quả của điều này là chương trình của bạn không bao giờ nên dựa vào macro đang hoạt động.
// 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);
Từ sự kết hợp giữa chương trình gọi abort () và không được đảm bảo để làm bất cứ điều gì, chỉ nên sử dụng các xác nhận để kiểm tra những thứ mà nhà phát triển đã giả sử thay vì, ví dụ, người dùng nhập một số chứ không phải là một chữ cái xử lý bằng các phương tiện khác).
assert
thường đưa ra một ngoại lệ" - trong C ++, nó không tăng "ngoại lệ" mà nó gọi là hủy bỏ ... nó hơi khác một chút.
#
ký tự không đưa ra nhận xét.
assert("error message", expression)
Các khẳng định tuyên bố máy tính tương tự như báo cáo kết quả chắc chắn bằng tiếng Anh.
Hãy xem
chương trình ví dụ khẳng định () trong C ++
Nhiều trình biên dịch cung cấp một macro khẳng định (). Macro assert () trả về TRUE nếu tham số của nó đánh giá TRUE và thực hiện một số loại hành động nếu nó đánh giá FALSE. Nhiều trình biên dịch sẽ hủy bỏ chương trình trên một assert () không thành công; những người khác sẽ ném một ngoại lệ
Một tính năng mạnh mẽ của macro khẳng định () là bộ tiền xử lý thu gọn nó thành không có mã nào nếu DEBUG không được xác định. Đó là một sự trợ giúp tuyệt vời trong quá trình phát triển, và khi sản phẩm cuối cùng xuất xưởng, không có hình phạt về hiệu năng cũng như không tăng kích thước của phiên bản thực thi của chương trình.
Ví dụ
#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
Hàm assert () có thể chẩn đoán lỗi chương trình. Trong C, nó được định nghĩa trong <assert.h>
và trong C ++, nó được định nghĩa trong <cassert>
. Nguyên mẫu của nó là
void assert(int expression);
Biểu thức đối số có thể là bất cứ điều gì bạn muốn kiểm tra - một biến hoặc bất kỳ biểu thức C nào. Nếu biểu thức ước lượng thành TRUE, khẳng định () không làm gì cả. Nếu biểu thức ước lượng thành FALSE, assert () hiển thị thông báo lỗi trên stderr và hủy bỏ thực thi chương trình.
Làm thế nào để bạn sử dụng khẳng định ()? Nó thường được sử dụng để theo dõi các lỗi chương trình (khác với các lỗi biên dịch). Một lỗi không ngăn chương trình biên dịch, nhưng nó khiến nó đưa ra kết quả không chính xác hoặc chạy không đúng cách (ví dụ như khóa). Chẳng hạn, một chương trình phân tích tài chính mà bạn viết đôi khi có thể đưa ra câu trả lời không chính xác. Bạn nghi ngờ rằng vấn đề được gây ra bởi biến lãi suất_ lấy một giá trị âm, điều này không bao giờ xảy ra. Để kiểm tra điều này, đặt câu lệnh
khẳng định (lãi_rate> = 0); tại các vị trí trong chương trình nơi lãi suất được sử dụng. Nếu biến không bao giờ trở thành âm, macro xác nhận () sẽ thông báo cho bạn. Sau đó, bạn có thể kiểm tra mã có liên quan để xác định nguyên nhân của vấn đề.
Để xem cách assert () hoạt động, hãy chạy chương trình mẫu bên dưới . Nếu bạn nhập giá trị khác 0, chương trình sẽ hiển thị giá trị và kết thúc bình thường. Nếu bạn nhập số không, macro xác nhận () buộc chấm dứt chương trình bất thường. Thông báo lỗi chính xác mà bạn thấy sẽ phụ thuộc vào trình biên dịch của bạn, nhưng đây là một ví dụ điển hình:
Xác nhận thất bại: x, danh sách tệp19_3.c, dòng 13 Lưu ý rằng, để assert () hoạt động, chương trình của bạn phải được biên dịch trong chế độ gỡ lỗi. Tham khảo tài liệu trình biên dịch của bạn để biết thông tin về việc bật chế độ gỡ lỗi (như được giải thích trong giây lát). Khi bạn biên dịch phiên bản cuối cùng trong chế độ phát hành, các macro xác nhận () sẽ bị tắt.
int x;
printf("\nEnter an integer value: ");
scanf("%d", &x);
assert(x >= 0);
printf("You entered %d.\n", x);
return(0);
Nhập một giá trị số nguyên: 10
Bạn đã nhập 10.
Nhập một giá trị số nguyên: -1
Thông báo lỗi: chấm dứt chương trình bất thường
Thông báo lỗi của bạn có thể khác nhau, tùy thuộc vào hệ thống và trình biên dịch của bạn, nhưng ý tưởng chung là như nhau.
Những thứ như 'tăng ngoại lệ' và 'tạm dừng thực thi' có thể đúng với hầu hết các trình biên dịch, nhưng không phải cho tất cả. (BTW, có những tuyên bố khẳng định thực sự đưa ra ngoại lệ không?)
Đây là một ý nghĩa thú vị, hơi khác của khẳng định được sử dụng bởi c6x và các trình biên dịch TI khác: khi thấy các tuyên bố khẳng định nhất định, các trình biên dịch này sử dụng thông tin trong câu lệnh đó để thực hiện các tối ưu hóa nhất định. Xấu xa.
Ví dụ trong 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;
}
Điều này cho trình biên dịch de các mảng được căn chỉnh trên các ranh giới 32 bit, do đó trình biên dịch có thể tạo ra các hướng dẫn cụ thể được thực hiện cho loại căn chỉnh đó.
Dự thảo tiêu chuẩn C ++ 11 N3337
http://www.open-std.org/jtc1/sc22/wg21/docs/ con / 2012 / n3337.pdf
19.3 Khẳng định
1 Tiêu đề <cassert>, được mô tả trong (Bảng 42), cung cấp một macro để ghi lại các xác nhận chương trình C ++ và một cơ chế để vô hiệu hóa kiểm tra xác nhận.
2 Nội dung giống như tiêu đề thư viện C chuẩn <assert.h>.
Dự thảo tiêu chuẩn C99 N1256
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
7.2 Chẩn đoán <assert.h>
1 Tiêu đề
<assert.h>
xác định macro xác nhận và tham chiếu đến một macro khác,NDEBUG
không được xác định bởi<assert.h>
. NếuNDEBUG
được định nghĩa là tên macro tại điểm trong tệp nguồn có chứa <assert.h>, macro xác nhận được định nghĩa đơn giản là#define assert(ignore) ((void)0)
Macro xác nhận được xác định lại theo trạng thái hiện tại của NDEBUG mỗi lần
<assert.h>
được đưa vào.2. Macro khẳng định sẽ được thực hiện như một macro, không phải là một hàm thực tế. Nếu định nghĩa macro bị chặn để truy cập một chức năng thực tế, hành vi không được xác định.
7.2.1 Chẩn đoán chương trình
7.2.1.1 Macro khẳng định
Tóm tắc
1.
#include <assert.h> void assert(scalar expression);
Sự miêu tả
2 Macro khẳng định đưa các xét nghiệm chẩn đoán vào các chương trình; nó mở rộng đến một biểu thức void. Khi được thực thi, nếu biểu thức (sẽ có kiểu vô hướng) là sai (nghĩa là so sánh bằng 0), macro xác nhận ghi thông tin về cuộc gọi cụ thể không thành công (bao gồm cả văn bản của đối số, tên của tập tin nguồn, số dòng mã nguồn, và tên của hàm chứa nó - sau này lần lượt là các giá trị của các macro tiền xử lý
__FILE__
và__LINE__
và các định danh__func__
) trên dòng sai số chuẩn trong một định dạng thực hiện xác định. 165) Sau đó gọi hàm hủy bỏ.Trả về
3 Macro khẳng định trả về không có giá trị.
Có ba lý do chính để sử dụng hàm assert () so với bình thường nếu khác và printf
Hàm assert () chủ yếu được sử dụng trong giai đoạn gỡ lỗi, thật tẻ nhạt khi viết nếu khác với câu lệnh printf mỗi khi bạn muốn kiểm tra một điều kiện thậm chí không thể thực hiện theo mã cuối cùng.
Trong các triển khai phần mềm lớn, assert rất tiện dụng khi bạn có thể làm cho trình biên dịch bỏ qua các câu lệnh khẳng định bằng cách sử dụng macro NDEBUG được xác định trước khi liên kết tệp tiêu đề cho hàm assert ().
assert () trở nên hữu ích khi bạn đang thiết kế một hàm hoặc một số mã và muốn có ý tưởng về những gì giới hạn mã sẽ và không hoạt động và cuối cùng bao gồm một nếu khác để đánh giá về cơ bản nó chơi với các giả định.
Đây là một hàm sẽ dừng thực thi chương trình nếu giá trị mà nó đã đánh giá là sai. Thông thường nó được bao quanh bởi một macro để nó không được biên dịch thành nhị phân kết quả khi được biên dịch với các cài đặt phát hành.
Nó được thiết kế để được sử dụng để kiểm tra các giả định bạn đã thực hiện. Ví dụ:
void strcpy(char* dest, char* src){
//pointers shouldn't be null
assert(dest!=null);
assert(src!=null);
//copy string
while(*dest++ = *src++);
}
Lý tưởng bạn muốn là bạn có thể tạo ra lỗi trong chương trình của mình, như gọi một hàm có đối số không hợp lệ và bạn nhấn một xác nhận trước khi nó phân tách (hoặc không hoạt động như mong đợi)
Ngoài ra, bạn có thể sử dụng nó để kiểm tra xem phân bổ động có thành công hay không.
Mã ví dụ:
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.
Tương tự như:
if (p == NULL) {
cout << "dynamic allocation failed" << endl;
exit(1);
}
new
ném một ngoại lệ về thất bại phân bổ trừ khi bạn chỉ định nothrow
(mà bạn đã không ở đây). Hơn nữa, định dạng của bạn là lạ và exit
là xấu xa.
assert()
chỉ để gỡ lỗi và dập tắt những thứ không bao giờ, không bao giờ xảy ra - rất lâu trước khi bản dựng phát hành được thực hiện.