2013-07-06 36 views
10

gì xảy ra nếu tôi xác định chức năng của tôi trong tập tin .h của tôi nhưĐiều gì sẽ xảy ra với chức năng nội tuyến bên ngoài?

extern int returnaint(void); 

, định nghĩa nó trong file .c liên quan như

inline int returnaint(void) { 
    return 1; 
} 

và bao gồm các tiêu đề trong một file .c và sử dụng chức năng? Khi tôi biên dịch những thứ seperatly, tạo một tệp đối tượng cho mỗi tệp .c và sau đó liên kết chúng, có phải là hàm nội tuyến được bao gồm hay điều gì xảy ra?

Tôi biết trình biên dịch có thể bỏ qua inline, nhưng điều gì sẽ xảy ra nếu nó không bỏ qua nó trong trường hợp này?

+2

Sau đó, bạn nhận được một lỗi mối liên kết. –

+2

@ H2CO3, sẽ không bao giờ có lỗi liên kết. Đơn vị biên dịch với định nghĩa 'inline' cũng thấy một khai báo' extern', vì vậy biểu tượng phải được phát ra. Xin vui lòng xem câu trả lời của tôi. –

+0

@JensGustedt Cảm ơn, đã bỏ phiếu. –

Trả lời

20

Đã thêm inline vào định nghĩa hàm trong tệp .c chỉ là không cần thiết.

  • đơn vị biên dịch của bạn của tập tin .c thấy một extern khai (không inline) và một inline nét. Do đó nó phát ra biểu tượng cho hàm trong tệp đối tượng.

  • Tất cả các đơn vị biên dịch khác chỉ nhìn thấy tuyên bố extern và để họ có thể sử dụng chức năng mà không gặp sự cố, nếu bạn liên kết tệp thực thi cuối cùng với tệp .o khác.

Thực tế, bạn chỉ gặp sai đường. Tính năng này được sử dụng để bạn có thể xóa inline trong tệp .h, hiển thị với tất cả mọi người. Định nghĩa này của hàm chỉ hoạt động như một tuyên bố của biểu tượng, giống như extern, nhưng không xác định nó.

An khai báo extern chỉ trong một .c tệp (đơn vị biên dịch) sau đó đảm bảo rằng biểu tượng được xác định tại đó.

Thuật ngữ là một chút bối rối, các inlinenét hoạt động như tuyên bố của biểu tượng, và externkhai đóng vai trò là định nghĩa của nó

+1

Điểm tốt. Tôi nghĩ rằng tôi nên di chuyển các chức năng nội tuyến của tôi vào tiêu đề! :-) – musicmatze

+0

Thêm nội tuyến vào đơn vị dịch thuật xác định hàm có hiệu lực. Kết quả có thể xảy ra là việc sử dụng hàm đã nói trong đơn vị biên dịch này sẽ được inlined. –

+0

@ UweKleine-König, không. Trình biên dịch là miễn phí để làm bất cứ điều gì vui lòng. Nếu định nghĩa của hàm được hiển thị, trình biên dịch có thể hoặc không chọn nội dòng, miễn là nó tuân thủ quy tắc "as-if". Không có gì thay đổi bằng cách thêm 'inline' vào định nghĩa đó. –

4

Nó sẽ không biên dịch. Từ C11 (ISO/IEC 9899: 2011) §6.7.4 Chức năng specifiers (nhấn mạnh thêm):

Bất kỳ chức năng với liên kết nội bộ có thể là một chức năng inline. Đối với một hàm có liên kết bên ngoài , các hạn chế sau đây áp dụng: Nếu hàm được khai báo với một trình chỉ định hàm nội dòng, thì nó cũng sẽ được xác định trong cùng một đơn vị dịch. Nếu tất cả các khai báo phạm vi tệp cho một hàm trong đơn vị dịch bao gồm hàm nội tuyến chỉ định không có extern, thì định nghĩa trong đơn vị dịch đó là định nghĩa nội tuyến . Định nghĩa nội tuyến không cung cấp định nghĩa bên ngoài cho hàm, và không cấm định nghĩa bên ngoài trong một đơn vị dịch khác. Định nghĩa nội tuyến cung cấp giải pháp thay thế cho định nghĩa bên ngoài, mà người dịch có thể sử dụng để thực hiện bất kỳ lệnh gọi nào đến hàm trong cùng một đơn vị dịch. Nó không được chỉ định cho dù một cuộc gọi đến các chức năng sử dụng định nghĩa nội tuyến hoặc định nghĩa bên ngoài. 140)

140) Từ một định nghĩa inline khác với định nghĩa bên ngoài tương ứng và từ bất kỳ định nghĩa inline tương ứng khác trong đơn vị dịch khác, tất cả các đối tượng tương ứng với tĩnh thời gian lưu trữ cũng là khác biệt trong mỗi các định nghĩa.

Tệp .c khác chỉ nhận khai báo của hàm inline từ tiêu đề, chứ không phải định nghĩa, do đó, nó chống lại quy tắc in đậm.

EDIT:

Như @Jens Gustedt chỉ ra, giải thích trước đây của tôi là sai, bởi vì trong câu hỏi của OP, hàm được khai báo là không inline trong file header:

extern int returnaint(void); 

Vì vậy, các tập tin .c khác sẽ xử lý nó như một chức năng bình thường.

+8

câu trả lời sai. các tệp '.c' khác không thấy' inline' khai báo trong '.h' chỉ có' ​​extern' chứ không phải 'inline'. –

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