Cách kết thúc mã C ++


267

Tôi muốn mã C ++ của tôi ngừng chạy nếu đáp ứng một điều kiện nhất định, nhưng tôi không chắc làm thế nào để làm điều đó. Vì vậy, tại bất kỳ thời điểm nào nếu một iftuyên bố là đúng chấm dứt mã như thế này:

if (x==1)
{
    kill code;
}

98
Sử dụng logic hợp lý. Trong main()trả về sử dụng, trong các hàm sử dụng một giá trị trả về thích hợp hoặc ném Ngoại lệ thích hợp. Đừng dùng exit()!
kay - SE là ác

6
@JonathanLeffler: Khi được biên dịch với NDEBUGđịnh nghĩa, assertcó khả năng sẽ trở thành không hoạt động, vì vậy bạn không nên dựa vào nó để tìm ra nhiều lỗi hơn là phát hiện ra lỗi.
MvG

13
@jamesqf: a returntừ main()là hoàn toàn hợp lý. Nó đặt mã thoát được chương trình báo cáo cho hệ điều hành, có thể hữu ích trong nhiều trường hợp (ví dụ nếu chương trình của bạn có thể được sử dụng như một phần của quy trình lớn hơn).
AAT

11
Điều thú vị là Q này là một bản sao của câu hỏi này từ 5 năm trước, câu trả lời được chấp nhận khá khác nhau: stackoverflow.com/questions/1116493/how-to-quito-ac-program Tôi đoán rằng cộng đồng phải mất 5 năm để học được điều đó một cách mù quáng gọi std :: exit có thể là xấu?
Brandin

5
Câu hỏi Tại sao sử dụng exit()được coi là xấu? - SO 25141737Làm thế nào để thoát khỏi chương trình C ++? - SO 1116493 hiện đang đóng như là bản sao của cái này. Phần đầu tiên có tham chiếu đến 'Phần mềm chỉ dành cho sự cố' có thể đáng xem, nếu chỉ để kích thích suy nghĩ của bạn về cách viết phần mềm mạnh mẽ.
Jonathan Leffler

Câu trả lời:


431

Có một số cách, nhưng trước tiên bạn cần hiểu tại sao việc dọn dẹp đối tượng lại quan trọng và do đó lý do std::exitbị gạt ra ngoài lề giữa các lập trình viên C ++.

RAII và Stack Unwinding

C ++ sử dụng một thành ngữ gọi là RAII , trong thuật ngữ đơn giản có nghĩa là các đối tượng nên thực hiện khởi tạo trong hàm tạo và dọn dẹp trong hàm hủy. Ví dụ, std::ofstreamlớp [có thể] mở tệp trong hàm tạo, sau đó người dùng thực hiện các thao tác đầu ra trên nó và cuối cùng ở cuối vòng đời của nó, thường được xác định bởi phạm vi của nó, hàm hủy được gọi là về cơ bản đóng tệp và xả bất kỳ nội dung bằng văn bản vào đĩa.

Điều gì xảy ra nếu bạn không truy cập vào hàm hủy để xóa và đóng tệp? Ai biết! Nhưng có lẽ nó sẽ không ghi tất cả dữ liệu mà nó được cho là ghi vào tệp.

Ví dụ, hãy xem xét mã này

#include <fstream>
#include <exception>
#include <memory>

void inner_mad()
{
    throw std::exception();
}

void mad()
{
    auto ptr = std::make_unique<int>();
    inner_mad();
}

int main()
{
    std::ofstream os("file.txt");
    os << "Content!!!";

    int possibility = /* either 1, 2, 3 or 4 */;

    if(possibility == 1)
        return 0;
    else if(possibility == 2)
        throw std::exception();
    else if(possibility == 3)
        mad();
    else if(possibility == 4)
        exit(0);
}

Điều gì xảy ra trong mỗi khả năng là:

  • Khả năng 1: Trả về cơ bản rời khỏi phạm vi chức năng hiện tại, vì vậy nó biết về sự kết thúc của vòng đời osdo đó gọi hàm hủy của nó và thực hiện dọn dẹp đúng cách bằng cách đóng và xả tệp vào đĩa.
  • Khả năng 2: Ném một ngoại lệ cũng đảm nhiệm vòng đời của các đối tượng trong phạm vi hiện tại, do đó thực hiện dọn dẹp đúng cách ...
  • Khả năng 3: Ở đây stack uninding đi vào hành động! Mặc dù ngoại lệ được ném vào inner_mad, trình duyệt sẽ chuyển qua ngăn xếp madmainđể thực hiện dọn dẹp đúng cách, tất cả các đối tượng sẽ bị phá hủy đúng cách, bao gồm ptros.
  • Khả năng 4: Vâng, đây? exitlà một hàm C và nó không nhận biết cũng không tương thích với các thành ngữ C ++. Nó không thực hiện dọn dẹp trên các đối tượng của bạn, kể cả ostrong cùng một phạm vi. Vì vậy, tệp của bạn sẽ không được đóng đúng cách và vì lý do này, nội dung có thể không bao giờ được ghi vào đó!
  • Các khả năng khác: Nó sẽ chỉ để lại phạm vi chính, bằng cách thực hiện một ẩn return 0và do đó có tác dụng tương tự như khả năng 1, tức là dọn dẹp đúng cách.

Nhưng đừng quá chắc chắn về những gì tôi vừa nói với bạn (chủ yếu là khả năng 2 và 3); tiếp tục đọc và chúng tôi sẽ tìm hiểu làm thế nào để thực hiện dọn dẹp dựa trên ngoại lệ thích hợp.

Những cách có thể kết thúc

Trở về từ chính!

Bạn nên làm điều này bất cứ khi nào có thể; luôn luôn thích quay lại chương trình của bạn bằng cách trả về trạng thái thoát thích hợp từ chính.

Người gọi chương trình của bạn, và có thể là hệ điều hành, có thể muốn biết liệu chương trình của bạn được thực hiện có thành công hay không. Vì lý do tương tự, bạn nên trả về 0 hoặc EXIT_SUCCESSđể báo hiệu rằng chương trình đã kết thúc thành công và EXIT_FAILUREđể báo hiệu chương trình kết thúc không thành công, bất kỳ hình thức giá trị trả về nào khác đều được xác định theo thực hiện ( §18.5 / 8 ).

Tuy nhiên, bạn có thể rất sâu trong ngăn xếp cuộc gọi và trả lại tất cả số đó có thể gây đau đớn ...

[Đừng] ném ngoại lệ

Ném một ngoại lệ sẽ thực hiện dọn dẹp đối tượng thích hợp bằng cách sử dụng ngăn xếp ngăn xếp, bằng cách gọi hàm hủy của mọi đối tượng trong bất kỳ phạm vi nào trước đó.

Nhưng đây là cái bẫy ! Nó được xác định theo thực thi cho dù việc hủy xếp chồng được thực hiện khi một ngoại lệ bị ném không được xử lý (bởi mệnh đề Catch (...)) hoặc ngay cả khi bạn có một noexcepthàm ở giữa ngăn xếp cuộc gọi. Điều này được nêu trong §15.5.1 [trừ.terminate] :

  1. Trong một số tình huống xử lý ngoại lệ phải được bỏ qua cho các kỹ thuật xử lý lỗi kém tinh tế. [Lưu ý: Những tình huống này là:

    [...]

    - khi cơ chế xử lý ngoại lệ không thể tìm thấy một handler cho một ngoại lệ ném (15.3), hoặc khi việc tìm kiếm một handler (15.3) gặp khối ngoài cùng của một hàm với một noexcept-specification rằng không cho phép ngoại lệ (15,4), hoặc [...]

    [...]

  2. Trong các trường hợp như vậy, std :: terminating () được gọi là (18.8.3). Trong trường hợp không tìm thấy trình xử lý phù hợp, nó được xác định theo thực thi cho dù ngăn xếp có bị hủy hay không trước khi std :: terminating () được gọi là [...]

Vì vậy, chúng ta phải bắt nó!

Đừng ném một ngoại lệ và bắt nó ở chính!

Vì các trường hợp ngoại lệ chưa được thực hiện có thể không thực hiện hủy bỏ ngăn xếp (và do đó sẽ không thực hiện dọn dẹp đúng cách) , chúng ta nên bắt ngoại lệ trong chính và sau đó trả về trạng thái thoát ( EXIT_SUCCESShoặc EXIT_FAILURE).

Vì vậy, một thiết lập có thể tốt sẽ là:

int main()
{
    /* ... */
    try
    {
        // Insert code that will return by throwing a exception.
    }
    catch(const std::exception&)  // Consider using a custom exception type for intentional
    {                             // throws. A good idea might be a `return_exception`.
        return EXIT_FAILURE;
    }
    /* ... */
}

[Đừng] std :: thoát

Điều này không thực hiện bất kỳ loại ngăn xếp ngăn xếp nào và không có đối tượng còn sống nào trên ngăn xếp sẽ gọi hàm hủy tương ứng của nó để thực hiện dọn dẹp.

Điều này được thi hành trong §3.6.1 / 4 [basic.start.init] :

Việc kết thúc chương trình mà không rời khỏi khối hiện tại (ví dụ: bằng cách gọi hàm std :: exit (int) (18.5)) không phá hủy bất kỳ đối tượng nào có thời gian lưu trữ tự động (12.4) . Nếu std :: exit được gọi để kết thúc chương trình trong quá trình hủy đối tượng có thời gian lưu trữ tĩnh hoặc luồng, chương trình có hành vi không xác định.

Hãy suy nghĩ về nó bây giờ, tại sao bạn sẽ làm một điều như vậy? Có bao nhiêu đồ vật đã làm bạn đau đớn?

Các lựa chọn thay thế [xấu khác]

Có nhiều cách khác để chấm dứt chương trình (trừ sự cố) , nhưng chúng không được khuyến nghị. Chỉ để làm rõ, họ sẽ được trình bày ở đây. Lưu ý cách kết thúc chương trình bình thường không có nghĩa là ngăn xếp ngăn xếp mà là trạng thái ổn cho hệ điều hành.

  • std::_Exit gây ra chấm dứt chương trình bình thường, và đó là nó.
  • std::quick_exitgây ra chấm dứt chương trình bình thường và gọi std::at_quick_exittrình xử lý, không thực hiện dọn dẹp nào khác.
  • std::exitgây ra một chấm dứt chương trình bình thường và sau đó gọi std::atexitxử lý. Các loại dọn dẹp khác được thực hiện như gọi các hàm hủy đối tượng tĩnh.
  • std::abortgây ra một chấm dứt chương trình bất thường, không có dọn dẹp được thực hiện. Điều này nên được gọi nếu chương trình kết thúc một cách thực sự, thực sự bất ngờ. Nó sẽ không làm gì ngoài việc báo hiệu cho HĐH về việc chấm dứt bất thường. Một số hệ thống thực hiện một bãi chứa lõi trong trường hợp này.
  • std::terminategọi các std::terminate_handlercuộc gọi std::aborttheo mặc định.

25
Điều này khá nhiều thông tin: đáng chú ý là tôi chưa bao giờ nhận ra rằng việc ném một ngoại lệ không được xử lý ở bất cứ đâu (ví dụ: một số newcú ném std::bad_allocvà chương trình của bạn đã quên bắt ngoại lệ đó ở bất cứ đâu) sẽ không giải phóng ngăn xếp đúng cách trước khi chấm dứt. Điều này có vẻ ngớ ngẩn với tôi: nó đã dễ dàng để thực chất quấn cuộc gọi đến maintrong một tầm thường try{- }catch(...){}khối đó sẽ đảm bảo ngăn xếp ươm được thực hiện đúng trong những trường hợp như vậy, hoàn toàn miễn phí (do đó tôi có nghĩa là: chương trình không sử dụng này sẽ không phải trả phạt). Có bất kỳ lý do cụ thể này không được thực hiện?
Marc van Leeuwen

12
@MarcvanLeeuwen một lý do có thể là gỡ lỗi: bạn muốn đột nhập vào trình gỡ lỗi ngay khi một ngoại lệ chưa được xử lý được đưa ra. Hủy bỏ ngăn xếp và dọn dẹp sẽ xóa bối cảnh của sự cố gây ra sự cố mà bạn muốn gỡ lỗi. Nếu không có trình gỡ lỗi nào, có lẽ tốt hơn là kết xuất lõi để phân tích hậu biến có thể được thực hiện.
Hugh Allen

11
Đôi khi trình duyệt của tôi bị lỗi (tôi đổ lỗi cho flash) và tiêu tốn vài gigabyte RAM và hệ điều hành của tôi đã bỏ các trang trên ổ cứng khiến mọi thứ chậm lại. Khi tôi đóng trình duyệt, nó sẽ giải phóng ngăn xếp thích hợp, nghĩa là tất cả các gigabyte RAM đó được đọc từ ổ cứng và được sao chép vào bộ nhớ chỉ để phát hành, phải mất một phút hoặc lâu hơn. Tôi rất mong họ đã sử dụng std::abortthay thế để HĐH có thể giải phóng tất cả bộ nhớ, ổ cắm và mô tả tệp mà không cần trao đổi trong một phút.
nwp

2
@nwp, mình hiểu cảm giác. Nhưng việc giết ngay lập tức có thể làm hỏng các tệp, không lưu các tab gần đây nhất của tôi, v.v :)
Paul Draper

2
@PaulDraper Tôi chắc chắn sẽ không thể chấp nhận được nếu trình duyệt không thể khôi phục các tab tôi đã mở trước khi mất điện. Tất nhiên, nếu tôi vừa mở một tab và chưa có thời gian để lưu nó, nó sẽ bị mất. Nhưng ngoài điều đó, tôi nói không có lý do gì để mất nó.
kasperd 17/05/2015

61

Như Martin York đã đề cập, lối ra không thực hiện việc dọn dẹp cần thiết như trả lại.

Luôn luôn tốt hơn để sử dụng trở lại ở nơi thoát. Trong trường hợp nếu bạn không ở trong main, bất cứ nơi nào bạn muốn thoát khỏi chương trình, hãy quay lại main trước.

Hãy xem xét ví dụ dưới đây. Với chương trình sau, một tệp sẽ được tạo với nội dung được đề cập. Nhưng nếu trả về được nhận xét & thoát không ghi chú (0), trình biên dịch không đảm bảo với bạn rằng tệp sẽ có văn bản được yêu cầu.

int main()
{
    ofstream os("out.txt");
    os << "Hello, Can you see me!\n";
    return(0);
    //exit(0);
}

Không chỉ thế này, việc có nhiều điểm thoát trong một chương trình sẽ khiến việc gỡ lỗi khó khăn hơn. Chỉ sử dụng lối thoát khi nó có thể được biện minh.


2
Bạn đề nghị gì để đạt được hành vi này trong một chương trình lớn hơn một chút? Làm thế nào để bạn luôn trở về chính sạch nếu ở đâu đó sâu hơn trong mã, một điều kiện lỗi được kích hoạt sẽ thoát khỏi chương trình?
Janusz

5
@Janusz, Trong trường hợp đó, bạn có thể sử dụng / ném ngoại lệ, nếu không trả về giá trị được xác định trước tức là có giá trị trả về từ hàm, ví dụ như trả về 0 khi thành công, 1 trong trường hợp không thành công, nhưng tiếp tục thực hiện , -1 trong trường hợp thất bại và thoát khỏi chương trình. Dựa trên giá trị trả về từ hàm, nếu đó là một lỗi, chỉ cần trả về từ chính sau khi thực hiện bất kỳ hoạt động dọn dẹp nào nữa. Cuối cùng, sử dụng lối ra một cách thận trọng, tôi không có ý tránh nó.
Narendra N

1
@NarendraN, "dọn dẹp cần thiết" là mơ hồ - HĐH sẽ cẩn thận (Windows / Linux) rằng bộ xử lý bộ nhớ và tệp được giải phóng đúng cách. Đối với đầu ra tệp "thiếu": Nếu bạn khẳng định rằng đây có thể là sự cố thực sự, hãy xem stackoverflow.com/questions/14105650/how-does-stdflush-work Nếu bạn gặp tình trạng lỗi, ghi nhật ký thích hợp cho bạn biết rằng chương trình của bạn đạt đến trạng thái không xác định và bạn có thể đặt điểm dừng ngay trước điểm đăng nhập của mình. Làm thế nào mà làm cho gỡ lỗi khó hơn?
Markus

2
Lưu ý rằng câu trả lời này đã được hợp nhất từ ​​câu hỏi Làm thế nào để thoát khỏi chương trình C ++? - SO 1116493 . Câu trả lời này đã được viết khoảng 6 năm trước khi câu hỏi này được hỏi.
Jonathan Leffler

return (EXIT_SUCCESS);thay vào đó hãy sử dụng C ++ hiện đại return(0)
Jonas Stein

39

Gọi std::exithàm.   


2
Các hàm hủy của đối tượng nào được gọi khi bạn gọi hàm đó?
Rob Kennedy

37
exit () không trả về. Vì vậy, không có ngăn xếp ngăn xếp có thể diễn ra. Ngay cả các đối tượng toàn cầu không bị phá hủy. Nhưng các hàm được đăng ký với atexit () sẽ được gọi.
Martin York

16
Vui lòng không gọi exit()khi mã thư viện của bạn đang chạy trong quy trình lưu trữ của tôi - cái sau sẽ thoát ra giữa hư không.
sharptooth

5
Lưu ý rằng câu trả lời này đã được hợp nhất từ ​​câu hỏi Làm thế nào để thoát khỏi chương trình C ++? - SO 1116493 . Câu trả lời này đã được viết khoảng 6 năm trước khi câu hỏi này được hỏi.
Jonathan Leffler

23

Mọi người đang nói "thoát cuộc gọi (mã trả về)", nhưng đây là hình thức xấu. Trong các chương trình nhỏ thì tốt, nhưng có một số vấn đề với điều này:

  1. Cuối cùng, bạn sẽ có nhiều điểm thoát khỏi chương trình
  2. Nó làm cho mã phức tạp hơn (như sử dụng goto)
  3. Nó không thể giải phóng bộ nhớ được phân bổ trong thời gian chạy

Thực sự, lần duy nhất bạn nên thoát vấn đề là với dòng này trong main.cpp:

return 0;

Nếu bạn đang sử dụng exit () để xử lý lỗi, bạn nên tìm hiểu về các ngoại lệ (và ngoại lệ lồng nhau), như một phương pháp thanh lịch và an toàn hơn nhiều.


9
Trong một môi trường đa luồng, một ngoại lệ được ném trong một luồng khác sẽ không được xử lý mặc dù main () - một số giao tiếp luồng chéo thủ công là cần thiết trước khi luồng cấp dưới hết hạn.
Steve Gilham

3
1. và 2. tùy thuộc vào lập trình viên, với việc ghi nhật ký thích hợp, đây không phải là vấn đề vì việc miễn trừ dừng vĩnh viễn. Đối với 3: Điều đó hoàn toàn sai, HĐH sẽ giải phóng bộ nhớ - có thể loại trừ các thiết bị nhúng / thời gian thực, nhưng nếu bạn đang làm điều đó, bạn có thể biết nội dung của mình.
Markus

1
Lưu ý rằng câu trả lời này đã được hợp nhất từ ​​câu hỏi Làm thế nào để thoát khỏi chương trình C ++? - SO 1116493 . Câu trả lời này đã được viết khoảng 6 năm trước khi câu hỏi này được hỏi.
Jonathan Leffler

1
Tuy nhiên, nếu xảy ra lỗi, bạn không nên trả về 0. Bạn nên trả về 1 (hoặc có thể một số giá trị khác, nhưng 1 luôn là lựa chọn an toàn).
Kef Schecter

14

return 0;đặt bất cứ nơi nào bạn muốn trong int main()và chương trình sẽ ngay lập tức đóng lại.


the nightman, @ evan-Carslake, và những người khác, tôi cũng sẽ nói thêm rằng câu hỏi SO # 36707 này đưa ra một cuộc thảo luận về việc liệu một tuyên bố trở lại có nên xảy ra ở bất cứ đâu trong một thói quen. Đây là một giải pháp; tuy nhiên, tùy thuộc vào tình huống cụ thể, tôi sẽ không nói đây là giải pháp tốt nhất.
localhost

1
OP không nói gì về điều này, vì vậy tôi nghĩ rằng khá là khó chịu khi cho rằng mã có nghĩa là nằm trong hàm main.
Marc van Leeuwen

@localhost Một tuyên bố trả lại là hoàn toàn tùy chọn trong mọi tình huống, trong mọi điều kiện. Tuy nhiên, int main()là khác nhau. Chương trình sử dụng int main()để bắt đầu và kết thúc. Không có cách nào khác để làm điều đó. Chương trình sẽ chạy cho đến khi bạn trả về đúng hay sai. Hầu như tất cả thời gian bạn sẽ trả về 1 hoặc đúng, để cho biết chương trình đã đóng đúng (ví dụ: có thể sử dụng sai nếu bạn không thể giải phóng bộ nhớ hoặc bất kỳ lý do nào.) Để chương trình tự chạy xong luôn là một ý tưởng tồi, ví dụ:int main() { int x = 2; int foo = x*5; std::cout << "blah"; }
Evan Carslake

@EvanCarslake Hiểu, nếu bạn nhận thấy một bình luận tôi đã đăng ở nơi khác cho câu hỏi này, tôi quen thuộc với điều này về int main; tuy nhiên, không phải lúc nào cũng có một câu trả lời đúng trong một thói quen chính. Một cảnh báo tiềm năng là cải thiện khả năng đọc mã; tuy nhiên, sử dụng một cái gì đó như cờ boolean thay đổi trạng thái để ngăn các phần mã nhất định chạy trong trạng thái ứng dụng đó. Cá nhân, tôi thấy một tuyên bố hoàn trả chung làm cho hầu hết các ứng dụng dễ đọc hơn. Cuối cùng, các câu hỏi về dọn dẹp bộ nhớ và đóng các đối tượng I / O đúng cách trước khi thoát.
localhost

2
@EvanCarslake bạn không trở về truetừ mainđể chỉ một chấm dứt đúng. Bạn phải trả về 0 hoặc EXIT_SUCCESS(hoặc, nếu bạn muốn, falsesẽ được chuyển đổi hoàn toàn thành 0) để biểu thị chấm dứt bình thường. Để chỉ ra thất bại bạn có thể trở lại EXIT_FAILURE. Bất kỳ ý nghĩa mã nào khác được xác định theo triển khai (trên các hệ thống POSIX, điều đó có nghĩa là mã lỗi thực tế).
Ruslan

11

Chương trình sẽ chấm dứt khi luồng thực thi đạt đến cuối chức năng chính.

Để chấm dứt nó trước đó, bạn có thể sử dụng hàm exit (int status), trong đó trạng thái là một giá trị được trả về bất cứ thứ gì bắt đầu chương trình. 0 thường biểu thị trạng thái không lỗi


2
Lưu ý rằng câu trả lời này đã được hợp nhất từ ​​câu hỏi Làm thế nào để thoát khỏi chương trình C ++? - SO 1116493 . Câu trả lời này đã được viết khoảng 6 năm trước khi câu hỏi này được hỏi.
Jonathan Leffler

11

Hoặc trả về một giá trị từ của bạn mainhoặc sử dụng exithàm. Cả hai lấy một int. Việc bạn trả về giá trị nào thực sự không quan trọng trừ khi bạn có quy trình bên ngoài đang theo dõi giá trị trả về.


3
Lưu ý rằng câu trả lời này đã được hợp nhất từ ​​câu hỏi Làm thế nào để thoát khỏi chương trình C ++? - SO 1116493 . Câu trả lời này đã được viết khoảng 6 năm trước khi câu hỏi này được hỏi.
Jonathan Leffler


9

Nói chung, bạn sẽ sử dụng exit()phương thức với trạng thái thoát thích hợp .

Zero có nghĩa là một hoạt động thành công. Một trạng thái khác không cho thấy một số loại vấn đề đã xảy ra. Mã thoát này được sử dụng bởi các quy trình cha (ví dụ: shell script) để xác định xem một quy trình đã chạy thành công chưa.


1
sử dụng lối ra CÓ THỂ có nghĩa là bạn có một vấn đề thiết kế. Nếu một chương trình sai chính xác, nó chỉ nên chấm dứt khi chính return 0;. Tôi giả sử exit()là như thế assert(false);và vì vậy chỉ nên được sử dụng trong phát triển để bắt các vấn đề sớm.
CoffeDeveloper

2
Lưu ý rằng câu trả lời này đã được hợp nhất từ ​​câu hỏi Làm thế nào để thoát khỏi chương trình C ++? - SO 1116493 . Câu trả lời này đã được viết khoảng 6 năm trước khi câu hỏi này được hỏi.
Jonathan Leffler

7

Ngoài việc gọi thoát (error_code) - gọi trình xử lý atexit, nhưng không phải là hàm hủy RAII, v.v. - ngày càng nhiều tôi đang sử dụng các ngoại lệ.

Càng ngày chương trình chính của tôi càng giống

int main(int argc, char** argv) 
{
    try {
        exit( secondary_main(argc, argv );
    }
    catch(...) {
        // optionally, print something like "unexpected or unknown exception caught by main"
        exit(1);
    }
}

trong đó junior_main trong đó tất cả những thứ ban đầu được đặt - tức là main ban đầu được đổi tên thành junior_main, và main stub ở trên được thêm vào. Đây chỉ là một tính năng tốt, do đó không có quá nhiều mã giữa khay và bắt chính.

Nếu bạn muốn, bắt các loại ngoại lệ khác.
Tôi khá thích bắt các loại lỗi chuỗi, như std :: string hoặc char *, và in các lỗi trong trình xử lý bắt chính.

Sử dụng các ngoại lệ như thế này ít nhất cho phép các hàm hủy RAII được gọi, để chúng có thể dọn dẹp. Mà có thể dễ chịu và hữu ích.

Nhìn chung, xử lý lỗi C - thoát và tín hiệu - và xử lý lỗi C ++ - ngoại lệ thử / bắt / ném - chơi với nhau không nhất quán ở mức tốt nhất.

Sau đó, nơi bạn phát hiện ra một lỗi

throw "error message"

hoặc một số loại ngoại lệ cụ thể hơn.


Nhân tiện: Tôi nhận thức rõ rằng sử dụng một kiểu dữ liệu như chuỗi, có thể liên quan đến cấp phát bộ nhớ động, không phải là một ý tưởng tốt trong hoặc xung quanh một trình xử lý ngoại lệ cho các ngoại lệ có thể liên quan đến việc hết bộ nhớ. Hằng chuỗi kiểu C không phải là vấn đề.
Krazy Glew

1
Không có điểm nào để gọi exittrong chương trình của bạn. Vì bạn đang ở trong main, bạn có thể return exitCode;.
Ruslan

-1

Nếu câu lệnh if của bạn nằm trong Loop Bạn có thể sử dụng

 break; 

Nếu bạn muốn thoát một số mã và tiếp tục lặp lại Sử dụng:

tiếp tục;

Nếu câu lệnh if của bạn không có trong Loop Bạn có thể sử dụng:

 return 0;

Or 




  exit();

-2

exit()Hàm ... anh chàng được định nghĩa theo stdlib.h

Vì vậy, bạn cần thêm một bộ tiền xử lý.

Đặt include stdlib.htrong phần tiêu đề

Sau đó sử dụng exit();bất cứ nơi nào bạn thích nhưng nhớ đặt một số interger trong ngoặc đơn của lối ra.

ví dụ:

exit(0);

-2

Nếu điều kiện tôi đang thử nghiệm thực sự là tin xấu, tôi sẽ làm điều này:

*(int*) NULL= 0;

Điều này mang lại cho tôi một coredump tốt đẹp từ nơi tôi có thể kiểm tra tình hình.


4
Điều này cũng có thể được tối ưu hóa, vì nó gây ra hành vi không xác định. Trong thực tế, toàn bộ nhánh thực thi có câu lệnh như vậy có thể bị trình biên dịch xóa sạch.
Ruslan

-2

Để phá vỡ một điều kiện, sử dụng return (0);

Vì vậy, trong trường hợp của bạn, nó sẽ là:

    if(x==1)
    {
        return 0;
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.