2009-08-06 35 views
83

Gần đây tôi đã có một dự án lớp học mà tôi đã phải thực hiện một chương trình với G ++. Tôi đã sử dụng một makefile và vì một lý do nào đó nó thỉnh thoảng lại để lại một tệp .h.gch. Đôi khi, điều này không ảnh hưởng đến việc biên dịch, nhưng thường xuyên như vậy nó sẽ dẫn đến trình biên dịch phát hành một lỗi cho một vấn đề đã được sửa chữa hoặc không có ý nghĩa. Tôi có hai câu hỏi:Tệp .h.gch là gì?

1) Tệp .h.gch là gì và tệp được sử dụng để làm gì? và

2) Tại sao nó gây ra các vấn đề như vậy khi nó không được dọn dẹp?

Cảm ơn sự giúp đỡ.

+8

gcc tạo chúng nếu bạn vô tình yêu cầu biên dịch tệp .h. Đừng làm điều đó :) (trừ khi bạn thực sự muốn tạo một tiêu đề được biên dịch trước) – jalf

+0

Ngoài thế giới ** GCC **, **. Gch ** được gọi là **. Pch **. – Patapoom

Trả lời

85

Tệp .gch của bạn là một tiêu đề được biên dịch trước.

Nếu không tìm thấy .gch thì các tệp tiêu đề bình thường sẽ được sử dụng.

Tuy nhiên, nếu dự án của bạn được đặt để tạo tiêu đề được biên dịch trước, nó sẽ tạo chúng nếu chúng không tồn tại và sử dụng chúng trong bản dựng tiếp theo.

Đôi khi, *.h.gch sẽ bị hỏng hoặc chứa thông tin lỗi thời, vì vậy việc xóa tệp đó và biên dịch lại tệp phải khắc phục.

14

a) Họ là tiêu đề precompiled: http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html

b) Họ chứa "cache" thông tin từ file .h và cần được cập nhật mỗi khi bạn thay đổi tệp .h tương ứng. Nếu điều này không xảy ra - bạn đã đặt các phụ thuộc sai trong dự án

26

Nếu bạn muốn biết về một tập tin, chỉ cần gõ vào terminal

file filename 

file a.h.gch cho:

GCC precompiled header (version 013) for C 
4

câu trả lời khác là hoàn toàn chính xác liên quan đến những gì một tập tin gch là với. Tuy nhiên, ngữ cảnh (trong trường hợp này, một người mới bắt đầu sử dụng g ++) là tất cả. Trong ngữ cảnh này, có hai quy tắc:

  1. Không bao giờ, bao giờ, đặt một tệp .h trên một dòng biên dịch g ++. Chỉ các tệp .cpp. Nếu tệp .h bị vô tình biên soạn, hãy xóa mọi tệp * .gch

  2. Không bao giờ, bao giờ, bao giờ đặt tệp .cpp trong câu lệnh #include.

Nếu quy tắc bị hỏng, tại một số điểm, sự cố được mô tả trong câu hỏi sẽ xảy ra. Nếu quy tắc hai bị hỏng, tại một số điểm, trình liên kết sẽ khiếu nại về các biểu tượng được xác định nhân.

+0

Bạn có thể chi tiết hơn về điểm đầu tiên không? – Darktega

+1

Đối với điểm 1, tôi sẽ sử dụng một hàm làm ví dụ. Trước khi một lập trình viên có thể gọi myfunc(), lập trình viên phải mô tả myfunc() cho trình biên dịch bằng cách sử dụng một mẫu thử nghiệm hàm. Nếu một vài tệp .cpp khác nhau gọi myfunc(), thì nguyên mẫu phải được cung cấp trong mỗi tệp .cpp. Đó là lỗi dễ bị loại ra nguyên mẫu trong mỗi tập tin .cpp. Do đó, nguyên mẫu hàm được đặt trong một tệp .h đượC#included trong mỗi tệp .cpp trong đó myfunc được gọi. Tệp tiêu đề chỉ chứa thông tin cho trình biên dịch, không phải mã được thực thi. Vì vậy, nó là vô nghĩa để đặt một tập tin .h trên một dòng g ++. – tgibson