2010-02-07 35 views
23

Kiến thức cơ bản của tôi về C và quá trình biên dịch gần đây đã biến mất. Tôi đã cố gắng tìm ra câu trả lời cho câu hỏi sau đây nhưng tôi không thể kết nối các giai đoạn biên dịch, liên kết và giai đoạn tiền xử lý. Một tìm kiếm nhanh trên Google cũng không giúp được gì nhiều. Vì vậy, tôi quyết định đi đến nguồn kiến ​​thức tối thượng :) Định nghĩa biến trong các tệp tiêu đề

Tôi biết: Không được định nghĩa các biến trong tệp .h. Ok của nó để tuyên bố chúng ở đó.

Lý do: Do tệp tiêu đề có thể được đưa vào từ nhiều vị trí, do đó xác định lại biến nhiều lần (Trình liên kết đưa ra lỗi).

Có thể làm việc xung quanh: Sử dụng tiêu đề bảo vệ trong tệp tiêu đề và xác định biến trong đó.

Có thực sự là một giải pháp: Không. Vì bộ phận bảo vệ đầu trang dành cho giai đoạn tiền xử lý. Đó là để nói với trình biên dịch rằng phần này đã được bao gồm và không bao gồm nó một lần nữa. Nhưng lỗi đa định nghĩa của chúng tôi xuất hiện trong phần liên kết - nhiều sau khi biên dịch.

Toàn bộ điều này khiến tôi bối rối về cách xử lý trước công việc liên kết &. Tôi nghĩ rằng tiền xử lý sẽ không bao gồm mã, nếu biểu tượng bảo vệ đầu trang đã được xác định. Trong trường hợp đó, không nên định nghĩa nhiều vấn đề biến cũng được giải quyết?

Điều gì xảy ra khi các chỉ thị tiền xử lý này lưu quy trình biên dịch từ việc xác định lại các ký hiệu trong bộ bảo vệ tiêu đề, nhưng trình liên kết vẫn nhận được nhiều định nghĩa của biểu tượng?

Trả lời

24

Trình bảo vệ tiêu đề bảo vệ bạn khỏi nhiều phần đính kèm trong một tệp nguồn duy nhất, không phải từ nhiều tệp nguồn. Tôi đoán vấn đề của bạn bắt nguồn từ việc không hiểu khái niệm này.

Nó không phải là nhân viên bảo vệ tiền xử lý được tiết kiệm trong thời gian biên dịch từ vấn đề này. Trên thực tế trong thời gian biên dịch, một tệp nguồn duy nhất được biên dịch thành một obj, các định nghĩa ký hiệu không được giải quyết. Tuy nhiên, trong trường hợp liên kết khi trình liên kết cố gắng giải quyết các ký hiệu definitons, nó bị nhầm lẫn khi thấy nhiều hơn một định nghĩa chồng nó để gắn cờ lỗi.

+0

yikes ... thực sự đơn giản :) – Methos

10

Bạn có hai tệp .c. Chúng được biên soạn riêng biệt. Mỗi tệp bao gồm tệp tiêu đề của bạn. Một lần. Mỗi người có một định nghĩa. Họ xung đột tại thời gian liên kết.

Giải pháp thông thường là:

#ifdef DEFINE_SOMETHING 
int something = 0; 
#endif 

Sau đó, bạn #define DEFINE_SOMETHING trong chỉ có một tập tin .c.

+0

Giải pháp tốt hơn là khai báo trong tiêu đề và định nghĩa chỉ trong một tệp .c. –

+0

Đồng ý, nhưng tôi cho rằng OP biết rằng :-) – bmargulies

24

Một điều mà tôi đã sử dụng trong quá khứ (khi biến trên thế giới đang thịnh hành):

tập tin var.h:

... 
#ifdef DEFINE_GLOBALS 
#define EXTERN 
#else 
#define EXTERN extern 
#endif 
EXTERN int global1; 
EXTERN int global2; 
... 

Sau đó, trong một tập tin .c (thường là một chứa chính()):

#define DEFINE_GLOBALS 
#include "var.h" 

Phần còn lại của tệp nguồn chỉ bao gồm "var.h" bình thường.

Lưu ý rằng DEFINE_GLOBALS không phải là trình bảo vệ đầu trang, mà là cho phép khai báo/xác định các biến tùy thuộc vào việc biến được xác định hay không. Kỹ thuật này cho phép một bản sao của các khai báo/định nghĩa.

+0

-1: Bạn không đưa ra câu trả lời cho câu hỏi thực tế ... – 3lectrologos

+11

Hmm, đúng vậy. Nó chỉ đơn thuần là một giải pháp tốt. 1 để bù đắp cho một downvote câm. –

+0

@Richard: FYI, không có ý định chơi chữ: Đó là "en thịnh hành", không phải "thịnh hành". – Multisync

8

Vệ sĩ tiêu đề dừng tệp tiêu đề được bao gồm nhiều lần trong cùng đơn vị dịch (ví dụ: trong cùng một tệp nguồn .c).Chúng không có hiệu lực nếu bạn đưa tệp vào hai hoặc nhiều đơn vị dịch.

+0

yup ... bạn nói đúng. – Methos

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