การใข้ Header Files ของ Standard C++

หมายเหตุ

  • บทความนี้เขียนครั้งแรกใน blog วิชา 517211 Programming Languages และเอามาลงใหม่ที่นี่อีกที
  • บทความนี้เกี่ยวข้องกับ Standard Library Headers ของ C/C++ เท่านั้น ไม่เกี่ยวข้องกับ Non-standard Library (เช่น conio.h หรือว่า library อื่นๆ ที่ download มาใช้เอง เช่นพวก image processing หรือว่า XML แต่อย่างใด)

ใน C++ (ตั้งแต่ C++98) เนี่ย header มันเปลี่ยนจาก .h เป็นไม่มี .h แทน เช่น iostream.h ก็เป็น iostream นอกจากนี้แล้วยังมีอีกเรื่อง คือ headers ทั้งหลายที่มาจาก C ซึ่งเปลี่ยนจาก .h เป็นใช้ c นำหน้า เช่น stdio.h เป็น cstdio แทน

โดยทุกอย่างที่อยู่ใน C++ standard library นี้จะอยู่ใน namespace ที่ชื่อ std ซึ่ง namespace ก็คือ ที่สำหรับเก็บชื่อ ว่่าชื่อนี้เป็นของอะไร เช่น std::cin คือ cin ที่อยู่ใน std เป็นต้น

ทีนี้ก็เลยกลายเป็นสาเหตุเล็กๆ น้อยๆ ที่เราควรจะสนใจและใช้ header ให้มันถูกต้องเสียที เวลาที่เขียน C++

  • ความเก่าและใหม่ เพราะว่า C++ บาง implementation ยังคงเก็บ .h headers ไว้เพื่อให้ compatible กับ code เก่าเท่านั้น (คือให้ code เก่าที่เคยเขียนมาสมัย pre-standard ยังคง compile ได้เท่านั้น) จะไม่มีการ update ให้ใช้ความสามารถใหม่ๆ ได้แต่อย่างใด

    ลองคิดว่าเป็นอารมณ์เดียวกับที่ Microsoft เลิก update Windows 98 ไปนานแล้ว …. แต่ว่าคุณยังเก็บ Win98 อยู่ เพราะว่ายังมีบางโปรแกรมที่ยังคงใช้มันอยู่ และใช้บน XP ไม่ได้น่ะแหละ

  • namespace พูดเป็นเล่นครับ นี่เรื่องใหญ่กว่าที่หลายๆ คนคิด ใครที่เคยเขียน C/C++ จะเข้าใจดี เรื่องความซ้ำกันของชื่อฟังค์ชัน หรือว่าชื่อ constant ต่างๆ เป็นปัญหาหลัก เนื่องจากว่ามันมีซ้ำไม่ได้เด็ดขาด (ห้ามประกาศซ้ำ ในหนึ่งโปรแกรม) สมมติว่าผมใช้ library บางตัว และมี function ที่ชื่อซ้ำกับ standard library หรือว่าซ้ำกันเองระหว่าง library อื่นๆ นี่จบกันเลย ต้องแก้โน่นแก้นี่เยอะมาก

    ทีนี้เป็นเรื่องครับ เพราะว่า standard library ของ C++ นั้นค่อนข้างจะใหญ่พอควร และมีชื่อที่ค่อนข้างโหลอยู่มากมาย เช่น vector (ใน header ชื่อ vector) หรือว่า max, find, count (ใน algorithm) เป็นต้น การที่พวกนี้อยู่ใน namespace std จะช่วยป้องกันปัญหาชื่อซ้ำกันได้บ้าง (เยอะเลยแหละ) เพราะว่าปกติชื่อมันจะไม่ซ้ำกันข้าม namespace

    ปัญหานี้มันก็อารมณ์เดียวกับคนชื่อซ้ำๆ กันในคณะ (เช่น ชื่อ ฝน หรือว่า เมย์ … ชื่ออะไรดีที่มีเยอะๆ?) แต่ว่าถ้าบอกว่า ฝน เอกคอมพ์ นี่คงจะน้อยลงไปเยอะเลย (โอกาสซ้ำกันก็ยังพอมีอยู่ แต่ว่าสำหรับ std namespace แล้วการันตีว่าไม่มีการซ้ำภายใน namespace เดียวกัน) .. งั้นการบอกว่า std::max ก็เหมือนกับบอกว่า เอกคอมพ์::ฝน น่ะแหละ … แต่ว่าถ้าชื่อไม่ค่อยจะโหล เช่น เอิง อะไรแบบนี้ก็แล้วไป (ถ้าเป็น C++ ก็คงจะพวก bind2nd อะไรทำนองล่ะมั้ง)

  • เรื่องความเข้ากันได้ของ C และ C++ เอง …. เรื่องนี้ไม่น่ามีล่ะครับ แต่ว่าก็ว่าไม่ได้ เพราะว่าไม่มีใครกำหนดไว้ชัดเจน แต่ว่าเนื่องจาก C และ C++ เอง นับวันก็ยิ่งจะแตกต่างกันในเรื่องของรายละเอียดเล็กๆ น้อยๆ มากขึ้นๆ เรื่อยๆ ถ้าเราใช้ .h library เมื่อไหร่ นั่นหมายถึงเราอาจจะใช้ library ของ C อย่างไม่รู้ตัวครับ นั่นแปลว่า ถึงเราจะแม่น devils in details ของ C++ มากแค่ไหน แต่ว่าถ้าเราใช้ของ C โดยที่เราคิดว่าใช้ของ C++ อยู่ล่ะ? ….. เราจะเจอปัญหาเล็กน้อยพอควรทีเดียว และเราจะไม่คิดด้วย ว่ามันเป็นปัญหาที่จุดนี้

    เรียกว่าถ้าเราจะใช้ C ก็ใช้ .h ให้ชัดเจน แต่ว่าถ้าจะใช้ C++ ก็เอา .h ออก และใช้ c ขึ้นหน้า (เช่น cstdio, cstdlib, cstring, cctype เป็นต้น)

    อ่อ ….​ และถึงตรงนี้เลยฝากไว้นิดเลยละกัน ว่า string.h ของ C (ที่มีพวก strlen) มันจะกลายเป็น cstring ใน C++ นะครับ ถ้า string ของ C++ จะเป็นอีกตัวนึง ซึ่งเป็นคนละเรื่องกันเลย

คงเป็นความรู้ประกอบการตัดสินใจในการเลือกใช้ header สำหรับการเขียน C/C++ ได้บ้างครับ