มีโค้ดกี่บรรทัดในโปรแกรมต่อไปนี้?
#include <iostream>
int main()
{
std::cout << "Hello, world!\n";
return 0;
}
คุณอาจตอบ 7 (หรือ 6 ถ้าคุณไม่นับบรรทัดว่างหรือ 4 ถ้าคุณไม่นับวงเล็บ)
คอมไพเลอร์ของคุณอย่างไรก็ตามเห็นสิ่งที่แตกต่างกันมาก:
~$ cpp hello.cpp | wc
18736 40822 437015
ใช่นั่นคือ 18.7 KLOC เพียงเพื่อ "สวัสดีโลก!" โปรแกรม. คอมไพเลอร์ C ++ ต้องแยกวิเคราะห์ทั้งหมด นี่คือเหตุผลสำคัญว่าทำไมการรวบรวม C ++ ใช้เวลานานมากเมื่อเทียบกับภาษาอื่นและทำไมภาษาสมัยใหม่จึงหลีกเลี่ยงไฟล์ส่วนหัว
คำถามที่ดีกว่าก็คือ
ทำไมไม่ C ++ มีไฟล์ส่วนหัว?
C ++ ได้รับการออกแบบให้เป็นชุดของ C ดังนั้นจึงต้องเก็บไฟล์ส่วนหัวไว้เพื่อใช้งานร่วมกันได้ย้อนหลัง
ตกลงเหตุใด C จึงมีไฟล์ส่วนหัว
เพราะรูปแบบการรวบรวมแยกดั้งเดิมของมัน ไฟล์อ็อบเจ็กต์ที่สร้างโดยคอมไพเลอร์ C จะไม่รวมข้อมูลประเภทใด ๆ ดังนั้นเพื่อป้องกันข้อผิดพลาดประเภทคุณจำเป็นต้องรวมข้อมูลนี้ในซอร์สโค้ดของคุณ
~$ cat sqrtdemo.c
int main(void)
{
/* implicit declaration int sqrt(int) */
double sqrt2 = sqrt(2);
printf("%f\n", sqrt2);
return 0;
}
~$ gcc -Wall -ansi -lm -Dsqrt= sqrtdemo.c
sqrtdemo.c: In function ‘main’:
sqrtdemo.c:5:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
sqrtdemo.c:5:5: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
~$ ./a.out
2.000000
การเพิ่มการประกาศประเภทที่เหมาะสมแก้ไขข้อบกพร่อง:
~$ cat sqrtdemo.c
#undef printf
#undef sqrt
int printf(const char*, ...);
double sqrt(double);
int main(void)
{
double sqrt2 = sqrt(2);
printf("%f\n", sqrt2);
return 0;
}
~$ gcc -Wall -ansi -lm sqrtdemo.c
~$ ./a.out
1.414214
แจ้งให้ทราบว่าไม่มี#include
s แต่เมื่อคุณใช้ฟังก์ชั่นภายนอกจำนวนมาก (ซึ่งโปรแกรมส่วนใหญ่จะใช้) การประกาศด้วยตนเองจะทำให้เกิดความเบื่อหน่ายและเกิดข้อผิดพลาดได้ง่าย มันง่ายกว่าที่จะใช้ไฟล์ส่วนหัว
ภาษาสมัยใหม่สามารถหลีกเลี่ยงไฟล์ส่วนหัวได้อย่างไร?
โดยใช้รูปแบบไฟล์วัตถุอื่นที่มีข้อมูลประเภท ตัวอย่างเช่นรูปแบบไฟล์ Java * .classมี "descriptors" ซึ่งระบุประเภทของฟิลด์และพารามิเตอร์เมธอด
นี่ไม่ใช่สิ่งประดิษฐ์ใหม่ ก่อนหน้านี้ (1987) เมื่อ Borland เพิ่ม "units" ที่คอมไพล์แล้วลงใน Turbo Pascal 4.0 มันเลือกที่จะใช้*.TPU
รูปแบบใหม่แทน Turbo C's *.OBJ
เพื่อลบความต้องการไฟล์ส่วนหัว