2010-09-07 12 views
5

Tôi có một câu hỏi thiết kế đơn giản (?).C: Lỗi ném khi kiểm tra tham số hoặc để nó chạm vào quạt?

Tôi đang viết một chương trình đơn giản, có một vài chức năng giống như thế này.

float foo (float* m,size_t n){ 

    float result; 
    //do some calculations, for example a sum 


    return result/n; 
} 

Tôi có một số câu hỏi về điều này, không có ý định mở lại một số cuộc chiến thánh thiện.

Tôi có nên thêm kiểm tra sanity trên n không? Nếu vậy, tôi nên cho người gọi biết như thế nào?

Trả lại -1 trông kỳ lạ trên phao;

float foo(float *m,size_t n){ 
    if (n == 0) return -1f 

    ... 
    } 

tùy chọn khác của tôi là một tham số ra

float foo(float *m,size_t n, int *error){ 

     if (n==0){ 
      *error = 1; 
      return 0f; 
     } 
     ... 
} 

cập nhật

Đây là loại một chương trình đồ chơi, chỉ cần cố gắng để thực hành một số nội dung. Câu hỏi đặt ra sự thật đó. Có lẽ tôi nên rephrase để "làm thế nào để xử lý lỗi mà không có (OOP) trường hợp ngoại lệ".

Đồng thời xem xét thử nghiệm n trước khi thực hiện cuộc gọi, nhưng không thích nó nhiều.

Mọi suy nghĩ? Cảm ơn trước.

+0

Có thể hữu ích khi nghe thêm về môi trường chức năng. Chúng có tồn tại trong cơ thể mã với các thực hành kiểm tra lỗi đã được thiết lập hay không hoặc mã của bên thứ ba có những kỳ vọng nhất định? Đây có phải là một dự án đồ chơi độc lập không? – TSomKes

+1

@TsomKes đã cập nhật câu hỏi của tôi. – Tom

Trả lời

6

Tôi đoán tùy chọn out parameter là tùy chọn tốt nhất. Nhưng tôi đoán nó sẽ tốt hơn theo cách khác. Sử dụng tham số ngoài để nhận kết quả và giá trị trả về để biểu thị trạng thái của cuộc gọi. Giống như

int foo(float *m, size_t n, float* result) 
{ 
    if(someFailureCondition) 
    return ERROR; // ERROR being an error integer 
    // else 
    // do some calculation 
    // set your result 
    return NO_ERROR; // NO_ERROR being an integer 
} 

Chỉnh sửa này: Giá trị trả về có thể tiết hơn để biểu thị trạng thái hiện tại của các tham số ra. Xem bình luận của Jamesdlin!

+0

Cảm ơn, đã không xem xét điều đó. Có vẻ phong cách hơn. – Tom

+1

Tôi cũng thích kiểu này hơn để kiểm tra lỗi thời gian chạy, nhưng bạn cũng nên nói rõ ràng (như là một phần của hợp đồng của hàm) trạng thái của tham số đầu ra là gì (ví dụ: chúng ở trạng thái không xác định, không bị ảnh hưởng hoặc được đặt) với một số giá trị cụ thể). – jamesdlin

2

Nếu -1 sẽ không được hàm trả về, bằng mọi cách trả về -1. Nhưng nếu vượt qua n = 0 sẽ không phá vỡ chức năng, thì nó không thực sự cần thiết. Tôi giả sử rằng n là kích thước của mảng m.

Lỗi xử lý là vấn đề ưu tiên. OpenGL xử lý lỗi bằng cách trả về một mã lỗi (-1 hoặc ngược lại) khi một hàm bị lỗi. Mã lỗi được trả về thông qua cuộc gọi đến GetLastError() (hoặc một cái gì đó tương tự). Điều này có vẻ như một giải pháp xử lý lỗi lý tưởng.

+0

có, n là số phần tử theo m. – Tom

1

Có những giá trị dấu chấm động đặc biệt bạn có thể sử dụng nếu bạn muốn - ví dụ, nếu thực hiện dấu chấm động của bạn hỗ trợ yên tĩnh Nans (Không-một-Số) sau đó bạn có thể sử dụng NAN vĩ mô từ math.h:

#include <math.h> 
float foo(float *m,size_t n) 
{ 
    if (n == 0) return NAN; 

    ... 
} 
+0

Được coi là nó, nhưng nó không phải là trường hợp "không làm gì cả"? – Tom

+0

Tôi không chắc chắn ý của bạn là gì. Nó giống như trường hợp '-1f' của bạn, ngoại trừ việc bạn thử nghiệm nó với' isnan() ', và nó sẽ lan truyền thông qua các tính toán dấu phẩy động tiếp theo. – caf

1

Bạn nên cho người gọi biết ngữ nghĩa của chức năng bằng cách ghi rõ mã của bạn.

Hợp đồng với chức năng của bạn là gì? Nếu người gọi được yêu cầu không vượt qua 0 cho n, thì điều đó cần được giải thích và chức năng nên sử dụng assert để xác minh rằng các yêu cầu đó được đáp ứng.Lỗi hợp lý cần được phát hiện sớm và những lỗi đó sẽ càng ngoạn mục càng tốt.

Bây giờ, nếu bạn đang viết mã cho thư viện sẽ được các nhà phát triển khác tiêu thụ và lo ngại rằng mọi người sẽ biên dịch với assert bị vô hiệu hóa, thì hợp lý là kết hợp với chế độ thất bại nhẹ nhàng luôn được bật:

if (n == 0) 
{ 
    assert(0); 
    return NAN; /* Or return some error code */ 
}