2010-09-22 40 views
34

Hallo!Thêm tin nhắn để xác nhận

Tôi đang tìm cách thêm thông điệp tùy chỉnh để xác nhận câu lệnh. Tôi đã tìm thấy câu hỏi này Add custom messages in assert? nhưng thông báo tĩnh ở đó. Tôi muốn thực hiện một việc như sau:

assert((0 < x) && (x < 10), std::string("x was ") + myToString(x)); 

Khi xác nhận không thành công, tôi muốn kết quả đầu ra bình thường cộng với ví dụ "x là 100".

+5

Tôi nghĩ ở đây bạn có [answer] tốt hơn (http://stackoverflow.com/questions/3692954/add-custom-messages-in-assert) –

+2

Hack xấu xí: 'if (fail_condition) khẳng định (!" Thông báo của tôi ");' –

+0

@MarkKCowan, tôi nghĩ rằng "xấu xí hack" của bạn thực sự là cách tốt hơn so với "&&" vá lên, bởi vì nó chỉ hiển thị thông báo :) – NL628

Trả lời

60

Bạn đã hết may mắn tại đây. Cách tốt nhất là xác định macro assert của riêng bạn.

Về cơ bản, nó có thể trông như thế này:

#ifndef NDEBUG 
# define ASSERT(condition, message) \ 
    do { \ 
     if (! (condition)) { \ 
      std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \ 
         << " line " << __LINE__ << ": " << message << std::endl; \ 
      std::terminate(); \ 
     } \ 
    } while (false) 
#else 
# define ASSERT(condition, message) do { } while (false) 
#endif 

này sẽ xác định các ASSERT vĩ mô chỉ nếu không debug vĩ mô NDEBUG không được định nghĩa.

Sau đó, bạn muốn sử dụng nó như thế này:

ASSERT((0 < x) && (x < 10), "x was " << x); 

Đó là một chút đơn giản hơn sử dụng của bạn vì bạn không cần phải stringify "x was "x một cách rõ ràng, điều này được thực hiện ngầm bằng vĩ mô.

+4

Tại sao làm {} trong khi (sai)? – tauran

+4

@tauran: Vì vậy, bạn có thể đặt dấu chấm phẩy sau macro khi sử dụng. –

+0

Tại sao không phải là 'do {} trong khi (false)' cho trường hợp '# else'? ;-) Cũng thường hữu ích để hiển thị mã nguồn khẳng định được xâu chuỗi '# condition'. Rõ ràng, EXIT_FAILURE cũng nên được ưu tiên hơn 1. +1 vì nó đang hình thành câu trả lời tốt nhất. –

6
#define ASSERT_WITH_MESSAGE(condition, message) do { \ 
if (!(condition)) { printf((message)); } \ 
assert ((condition)); } while(false) 
7

Thay thế tốt hơn là dạy trình gỡ rối dừng lại khi xác nhận khi không thành công, bạn có thể kiểm tra không chỉ giá trị x mà còn bất kỳ thông tin nào khác bao gồm ngăn xếp cuộc gọi. Có lẽ, đây là những gì bạn đang thực sự tìm kiếm. Triển khai mẫu được đề cập ở đây Ways to show your co-programmers that some methods are not yet implemented in a class when programming in C++

+0

+1 Không phải những gì tôi đã tìm kiếm, nhưng có thể thực sự hữu ích vào một ngày nào đó. – tauran

2

Vì lợi ích của sự hoàn chỉnh, tôi đã công bố một thả trong 2 tác phẩm khẳng định thi hành vĩ mô trong C++:

#include <pempek_assert.h> 

int main() 
{ 
    float min = 0.0f; 
    float max = 1.0f; 
    float v = 2.0f; 
    PEMPEK_ASSERT(v > min && v < max, 
       "invalid value: %f, must be between %f and %f", v, min, max); 

    return 0; 
} 

sẽ nhắc bạn với:

Assertion 'v > min && v < max' failed (DEBUG) 
    in file e.cpp, line 8 
    function: int main() 
    with message: invalid value: 2.000000, must be between 0.000000 and 1.000000 

Press (I)gnore/Ignore (F)orever/Ignore (A)ll/(D)ebug/A(b)ort: 

Ở đâu

  • (I) gnore: bỏ qua xác nhận hiện tại
  • Bỏ qua (F) orever: nhớ các tập tin và đường nơi khẳng định sa thải và bỏ qua nó để thực hiện còn lại của chương trình
  • Ignore (A) ll: bỏ qua tất cả khẳng định còn lại (tất cả các file và dòng)
  • (D) ebug: đột nhập vào trình gỡ lỗi nếu kèm theo, nếu không abort() (trên Windows, hệ thống sẽ nhắc nhở người dùng đính kèm một debugger)
  • A (b) ort: gọi abort() ngay

Bạn có thể tìm hiểu thêm về nó ở đó:

Hy vọng rằng sẽ giúp.

7

Có một số thủ thuật cũ để bao gồm các thông điệp mà không cần viết thói quen riêng của bạn:

Việc đầu tiên là này:

bool testbool = false; 
assert(("this is the time", testbool)); 

Ngoài ra còn có:

bool testbool = false; 
assert(testbool && "This is a message"); 

Người đầu tiên hoạt động, bởi vì kết quả biểu thức parens bên trong là giá trị của 'testbool'. Cách thứ hai hoạt động, bởi vì giá trị của chuỗi sẽ không khác.

0

đi cùng với câu trả lời Konrad Rudolf của bạn có thể làm điều đó chính xác hơn một chút với

#include <assert.h> 
#include <stdio.h> 
#define ASSERT(condition,...) assert(\ 
    condition|| \ 
    (fprintf(stderr,__VA_ARGS__)&&fprintf(stderr," at %s:%d\n",__FILE__,__LINE__)) \ 
); 

mà cũng làm việc trong C,

nó hoạt động bằng cách sử dụng ý tưởng chung từ một số các câu trả lời cho câu hỏi bạn đã liên kết, nhưng macro cho phép nó linh hoạt hơn một chút

Các vấn đề liên quan