2010-05-21 35 views
28

thực hành tốt dictates rằng đối số chương trình con trong Fortran nên mỗi có một ý định nào đó (ví dụ intent(in), intent(out) hoặc intent(inout) như mô tả this question):ý định Fortran (inout) so với bỏ qua ý định

subroutine bar (a, b) 
    real, intent(in) :: a 
    real, intent(inout) :: b 
    b = b + a 
    ... 

Tuy nhiên, không chỉ định một mục đích là Fortran hợp lệ:

subroutine bar (a, b) 
    real, intent(in) :: a 
    real :: b 
    b = b + a 
    ... 

có bất kỳ sự khác biệt thực vượt thời gian biên dịch kiểm tra cho một cuộc tranh cãi quy định như intent(inout) và một cuộc tranh cãi mà không có một quy định tại lều? Có điều gì tôi nên lo lắng không nếu tôi cải thiện ý định về mã nguồn, miễn phí, có chủ ý?

Trả lời

20

Theo Sổ tay Fortran 2003 bởi Adams, và cộng sự, có một sự khác biệt giữa một đối số (inout) đối số và tham chiếu không có ý định cụ thể. Đối số thực tế (ví dụ: trong người gọi) trong trường hợp ý định (inout) phải luôn có thể xác định được. Nếu ý định không được chỉ định, đối số phải được xác định nếu thực hiện các nỗ lực của chương trình con để xác định đối số giả định. có thể xác định có nghĩa là đặt giá trị: dummy_arg = 2.0. Rõ ràng đối số thực tế phải là một biến nếu điều này được thực hiện. Đối với ý định (inout) các đối số thực tế phải được xác định có hay không chương trình con thực hiện điều này. Không có ý định nào được chỉ định, nó phụ thuộc vào những gì xảy ra trên lời gọi cụ thể của chương trình con đó - nếu chương trình con không định nghĩa biến, nó là OK; nếu nó có, hơn là có một vấn đề - các trường hợp như viết cho một đối số thực tế là một hằng số rõ ràng sẽ gây ra vấn đề.

Điều này không có nghĩa là trình biên dịch sẽ chẩn đoán tất cả các trường hợp này - tiêu chuẩn yêu cầu trình biên dịch để chẩn đoán là một vấn đề khác. Sẽ gần như không thể phát hiện tất cả các lỗi của yêu cầu trường hợp không được chỉ định trong thời gian biên dịch, vì các vi phạm phụ thuộc vào luồng thời gian chạy của mã. Nó dễ dàng hơn nhiều cho trình biên dịch để chẩn đoán trường hợp ý định (inout) và cảnh báo bạn về các vấn đề với mã.

5

Câu hỏi của bạn nhắc tôi tự hỏi (rất nhiều việc cần làm ngay bây giờ) cho dù bạn có thể gặp phải sự khác biệt về hành vi nếu mã của bạn vượt qua PARAMETER như một đối số thực tế mà chương trình con của bạn sau đó cố ghi vào. Nếu không có khai báo INTENT, trình biên dịch có thể cho phép điều này xảy ra, dẫn đến hành vi kỳ quặc. Với tuyên bố tôi mong đợi một lỗi biên dịch thời gian. Bạn có thể nghĩ rằng không có sự khác biệt giữa INOUT và không có khai báo INTENT, nhưng đừng quên rằng có rất nhiều chương trình Fortran cũ và khả năng tương thích với các phiên bản ngôn ngữ cũ là một tính năng quan trọng của phiên bản mới. tiêu chuẩn. Nếu nó là đúng (nhưng tinh ranh) FORTRAN77 thì rất nhiều người mong đợi mã của họ vẫn đúng (vẫn còn tinh ranh) với một trình biên dịch Fortran 90+.

Đọc nhanh tiêu chuẩn năm 2003 cho biết có sự khác biệt giữa INOUT và không có INTENT, nhưng cần phải đọc kỹ hơn. Nếu bạn kiểm tra điều này, hãy cho chúng tôi biết kết luận của bạn; nếu tôi có thời gian sau, tôi sẽ tự mình kiểm tra và cho bạn biết.

+3

Tôi đã xây dựng bốn trường hợp thử nghiệm cố gắng sửa đổi một tham số trong một chương trình con. Hai thử nghiệm với các chương trình con bên ngoài - tức là trong một tệp của chính chúng - có và không có ý định (inout). Trình biên dịch không phàn nàn về bất kỳ của những người. Đây không phải là một bất ngờ (không có giao diện) và các kết quả exe segfaults. Tôi đã bị mắc kẹt chương trình con trong một mô-đun cho hai thử nghiệm cuối cùng và xem segfault cho trường hợp không có ý định và lỗi trình biên dịch ("đối số thực tế tại (1) phải được xác định là đối số giả 'b' là INTENT = OUT/INOUT ") với giao diện. Điều này là với gfortran 4.4.4-2 từ một hệ thống debian. –

+0

Tuyệt vời, cả hai chúng tôi đều học được điều gì đó. –

+1

Các thông số ngày này được đặt trong phần chỉ đọc được đánh dấu của bộ nhớ, nhưng điều này không phải lúc nào cũng đúng. Ví dụ nổi tiếng trong các trình biên dịch rất cũ đã xác định lại các hằng số số http://coding.derkeiler.com/Archive/Fortran/comp.lang.fortran/2005-01/0485.html –

3

Để hiểu vai trò của mục đích vào/ra, bạn cần biết rằng nội bộ, Fortran hiệu quả chuyển biến theo tham chiếu. Điều này không phải lúc nào cũng giống như thực sự truyền qua tham chiếu.

Nếu bạn chuyển một phần con nội bộ của một mảng 2-D vào một chương trình con, nghĩa là: data(i1:i2, j1:j2), thì Fortran sẽ sao chép dữ liệu đó vào một phần bộ nhớ liền kề và chuyển địa chỉ mới này đến thường trình. Khi trở về, dữ liệu được sao chép trở lại vị trí ban đầu của nó.

Bằng cách chỉ định INTENT, trình biên dịch có thể biết bỏ qua một trong các thao tác sao chép.

Nó không chỉ hoạt động như một sự không an toàn để sửa đổi dữ liệu mà bạn muốn giữ nguyên, mà còn có thể tăng tốc mã của bạn khi xử lý các tập dữ liệu lớn.

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