2010-12-30 27 views
11

Tôi muốn xử lý lỗi trong chương trình C++ của mình, vì vậy tôi đã tạo một số lớp ngoại lệ để quản lý các lỗi đó, nhưng tôi muốn chỉ định dòng nào trong chương trình của tôi đã xảy ra lỗi.cách nhận số dòng lỗi trong chương trình C++

Tôi đã thông qua LINE macro cho hàm tạo của lớp ngoại lệ của tôi.

Ví dụ:

void f(int i){ // LINE A 
    if(i<0) 
    throw(OutOfRange("message", __LINE__); // LINE B 
} 

void main(){ 

    try{ 
    f(-6); // LINE C 
    } 
    catch(const OutOfRange& error){ 
    //do something 
    } 

} 

Trong ví dụ này tôi chỉ có thể nhận được số dòng B, nhưng tôi muốn để có được số dòng A và dòng C.

Bất kỳ ý tưởng nào, ở đâu và cách sử dụng LINE macro ??

Cảm ơn.

+1

Bạn muốn có một stacktrace/traceback. – delnan

+0

http://www.decompile.com/cpp/faq/file_and_line_error_string.htm – anno

Trả lời

8

Bạn đang tìm kiếm cho một dấu vết ngăn xếp và không có cách nào để lấy nó. Một cái gì đó tương tự như có thể đạt được với:

struct SourcePoint 
{ 
    const char *filename; 
    int line; 
    SourcePoint(const char *filename, int line) 
     : filename(filename), line(line) 
    { } 
}; 

std::vector<SourcePoint> callstack; 

struct SourcePointMarker 
{ 
    SourcePointMarker(const char *filename, int line) 
    { 
     callstack.push_back(SourcePoint(filename, line); 
    } 

    ~SourcePointMarker() 
    { 
     callstack.pop_back(); 
    } 
} 

#define MARK_FUNCTION \ 
    SourcePointMarker sourcepointmarker(__FILE__, __LINE__); 

Sau đó, ngay sau khi bắt đầu mỗi chức năng (hoặc địa điểm ưa thích), bạn chỉ cần thêm một dòng ... ví dụ

int myFunction(int x) 
{ 
    MARK_FUNCTION 
    ... 
} 

Sử dụng phương pháp này trong xử lý lỗi của bạn, bạn có thể biết ai được gọi bởi ai và như vậy (tất nhiên bạn sẽ chỉ biết các chức năng hoặc các địa điểm đã được trang bị với MARK_FUNCTION). Nếu điều này là cần thiết chỉ trong quá trình thử nghiệm (và không phải trong sản xuất) thì có lẽ bạn nên chỉ cho phép các bãi lõi và tìm hiểu cách chạy một trình gỡ rối trong phân tích sau giết mổ.

+1

có đó là những gì tôi đang tìm kiếm, tôi sẽ cố gắng bây giờ, cảm ơn rất nhiều. – CHAKRI

1

Dòng C sẽ là gần như không thể (Tôi không thể nghĩ ra một cách ... ngoại trừ bằng cách thông qua một cuộc tranh luận thứ hai để f, __LINE__

Dòng A như sau:.

void f(int i){ const int lineA = __LINE__; 
    if(i<0) 
    throw(OutOfRange("message", __LINE__); // LINE B 
} 
+0

bạn có nghĩa là void f (int i) {const int lineA = __LINE__; nếu (i <0) ném (OutOfRange ("message", lineA); // LINE B } – CHAKRI

+0

cảm ơn câu trả lời của bạn, nhưng tôi nghĩ rằng "LINE C" không phải là không thể gây ra hầu hết các trình biên dịch sử dụng nó !! – CHAKRI

+1

@CHAKRI: Trình biên dịch có thể thực hiện nhiều, nhiều, nhiều thứ mà bạn không thể làm trong Chuẩn C++. – Puppy

1

Bạn Không có cách nào trong tiêu chuẩn C++ mà bạn có thể tìm thấy dòng C mà không chuyển nó vào như một đối số (f(-6, __LINE__)), và không có cách nào ở tất cả mà bạn có thể tìm thấy Line A.

+0

+1, nhưng tôi muốn nói "dấu vết ngăn xếp * hoặc * trình gỡ lỗi", vì một dấu vết ngăn xếp có thể thu được ngay cả khi không có trình gỡ rối bên ngoài (xem ví dụ: hàm backtrace') –

+0

ok có lẽ tôi sẽ đặt nó làm đối số. Cảm ơn bạn – CHAKRI

1

Khuôn khổ CPPUNit sử dụng macro thay vì chức năng. Bằng cách đó bạn có thể dễ dàng nhận được số dòng ở cùng một vị trí mà macro được gọi.

Tôi không nghĩ đó là một cách tiếp cận hợp lệ theo nghĩa chung, nhưng bạn có thể thấy thú vị khi xem xét cách các nhà phát triển CPPUnit đã làm điều đó.

+0

+1. Xem xét việc thực hiện macro assert(); Tôi đã tạo ra một macro khẳng định tương tự(), mà ném một ngoại lệ std :: logic_error thay vì gọi std :: abort() khi không xác nhận. – Raedwald

+0

ok Tôi sẽ xem xét điều này, cảm ơn – CHAKRI

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