จะดีกว่าการทำเอกสารฟังก์ชั่นในไฟล์ส่วนหัวหรือไฟล์ต้นฉบับ?


86

ในภาษาที่แยกความแตกต่างระหว่างไฟล์ "แหล่งที่มา" และ "ส่วนหัว" (ส่วนใหญ่ C และ C ++) จะดีกว่าฟังก์ชั่นเอกสารในไฟล์ส่วนหัวหรือไม่:

(ขโมยจากCCAN )

/**
 * time_now - return the current time
 *
 * Example:
 *  printf("Now is %lu seconds since epoch\n", (long)time_now().tv_sec);
 */
struct timeval time_now(void);

หรือในไฟล์ต้นฉบับ?

(ขโมยจาก PostgreSQL)

/*
 * Convert a UTF-8 character to a Unicode code point.
 * This is a one-character version of pg_utf2wchar_with_len.
 *
 * No error checks here, c must point to a long-enough string.
 */
pg_wchar
utf8_to_unicode(const unsigned char *c)
{
...

โปรดทราบว่าบางสิ่งมีการกำหนดไว้ในส่วนหัวเท่านั้นเช่น structs, macros และstatic inlineฟังก์ชั่น ฉันแค่พูดถึงสิ่งที่ประกาศในไฟล์ส่วนหัวและกำหนดไว้ในไฟล์ต้นฉบับ

นี่คือข้อโต้แย้งที่ฉันสามารถนึกได้ ฉันกำลังเอนไปยังการจัดทำเอกสารในไฟล์ต้นฉบับดังนั้นข้อโต้แย้ง "Pro-header" ของฉันอาจค่อนข้างอ่อนแอ

Pro-ส่วนหัว:

  • ผู้ใช้ไม่จำเป็นต้องมีซอร์สโค้ดเพื่อดูเอกสาร
    • แหล่งที่มาอาจไม่สะดวกหรือเป็นไปไม่ได้ที่จะได้รับ
    • สิ่งนี้ทำให้ส่วนต่อประสานและการนำไปใช้งานแยกออกจากกัน

Pro-แหล่งที่มา:

  • มันทำให้ส่วนหัวสั้นลงมากทำให้ผู้อ่านมองเห็นมุมมองของโมดูลโดยรวม
  • มันจับคู่เอกสารของฟังก์ชั่นกับการใช้งานทำให้ง่ายขึ้นที่จะเห็นว่าฟังก์ชั่นทำในสิ่งที่มันบอกว่ามันทำ

เมื่อตอบคำถามโปรดระวังข้อโต้แย้งโดยพิจารณาจากเครื่องมือและ "โมเดิร์นไอดี" ที่สามารถทำได้ ตัวอย่าง:

  • Pro-header: การพับโค้ดสามารถช่วยให้ส่วนหัวที่มีความคิดเห็นสามารถนำทางได้มากขึ้นโดยการซ่อนความคิดเห็น
  • Pro-source: คุณลักษณะของcscopeFind this global definitionจะนำคุณไปยังไฟล์ต้นฉบับ (โดยนิยามคือ) แทนที่จะเป็นไฟล์ส่วนหัว (โดยที่การประกาศคือ)

ฉันไม่ได้บอกว่าอย่าโต้แย้งเช่นนั้น แต่โปรดจำไว้ว่าไม่ใช่ทุกคนที่พอใจกับเครื่องมือที่คุณใช้เหมือนที่คุณเป็น


คำถามเดียวกันสามารถนำไปใช้กับ Pascal / Delphi โดยที่เราไม่มีไฟล์ต้นฉบับและไฟล์ส่วนหัว แต่เป็นส่วนต่อประสานและส่วนนำไปใช้
Jan Doggen

คำตอบ:


96

มุมมองของฉัน...

  • เอกสารวิธีใช้ฟังก์ชันในไฟล์ส่วนหัวหรือใกล้เคียงกับการประกาศอย่างแม่นยำมากขึ้น

  • เอกสารวิธีการทำงานของฟังก์ชั่น (หากไม่ชัดเจนจากรหัส) ในไฟล์ต้นฉบับหรือใกล้เคียงกับคำจำกัดความมากขึ้น

สำหรับสิ่งที่น่าสนใจในส่วนหัวคุณไม่จำเป็นต้องใช้เอกสารที่ปิด - คุณสามารถจัดทำเอกสารกลุ่มการประกาศพร้อมกันได้

ผู้พูดควรสนใจข้อผิดพลาดและข้อยกเว้น (หากสามารถแปลได้เนื่องจากพวกเขาเผยแพร่ผ่านเลเยอร์สิ่งที่เป็นนามธรรม) ดังนั้นสิ่งเหล่านี้ควรได้รับการบันทึกไว้ใกล้กับคำประกาศที่เกี่ยวข้อง


13
+1 - คือเอกสารส่วนต่อประสานในส่วนหัว รายละเอียดเลือดของวิธีการและเหตุผลในแหล่งที่มา
quick_now

2
สำหรับส่วนหัวของห้องสมุดที่ไม่มีแหล่งที่มาอาจเพิ่มเงื่อนไขก่อนและหลัง ฯลฯ เพื่อช่วยในการทดสอบ บวกเพิ่มประสิทธิภาพ O (n) หากเหมาะสมดังนั้นผู้ใช้ห้องสมุดสามารถเลือกอย่างชาญฉลาด
Patrick Hughes

โดยธรรมชาติบางครั้งการประกาศและคำจำกัดความเป็นหนึ่งเดียวกัน
Deduplicator

@Dupuplicator - เมื่อกฎเดิมยังคงนำไปสู่สิ่งที่ถูกต้องแม้ในกรณีพิเศษทำไมสะท้อนกฏเหล่านั้นสำหรับทุกกรณีพิเศษ นักต้มตุ๋นซ้ำซ้อนไม่ควรต้องการอย่างนั้นหรือ
Steve314

1
@Dupuplicator - แน่นอนว่าเป็นเหตุผลที่คิดอย่างมากสำหรับการไม่ทำตามคำแนะนำของคุณ แต่ฉันก็ยังยึดติดอยู่กับมัน
Steve314

34

หากคุณกำลังจะใช้เครื่องมือเช่นDoxygen (หมายเหตุในตัวอย่างแรกที่ดูเหมือนว่าความคิดเห็น Doxygen เพราะมันเริ่มต้นด้วย/**) มันไม่สำคัญเลย - Doxygen จะมองผ่านไฟล์ส่วนหัวและแหล่งที่มาของคุณและค้นหา ความคิดเห็นทั้งหมดเพื่อสร้างเอกสาร

อย่างไรก็ตามฉันมีแนวโน้มที่จะแสดงความคิดเห็นเอกสารในส่วนหัวที่มีการประกาศ ลูกค้าของคุณจะจัดการกับส่วนหัวเพื่อเชื่อมต่อกับซอฟต์แวร์ของคุณส่วนหัวคือสิ่งที่พวกเขาจะรวมอยู่ในไฟล์ต้นฉบับของพวกเขาเองและนั่นคือสิ่งที่พวกเขาจะต้องมองหาก่อนเพื่อดูว่า API ของคุณเป็นอย่างไร

ถ้าคุณดูไลบรารี่ลินุกซ์เป็นส่วนใหญ่ระบบการจัดการแพกเกจลีนุกซ์ของคุณมักจะมีแพ็คเกจที่มีเพียงไบนารีของไลบรารี (สำหรับผู้ใช้ "ปกติ" ที่มีโปรแกรมที่ต้องการไลบรารี) และคุณมีแพ็คเกจ "dev" ที่ มีส่วนหัวสำหรับห้องสมุด โดยทั่วไปแล้วซอร์สโค้ดจะไม่ได้รับการจัดหาโดยตรงในแพ็คเกจ มันจะยุ่งยากมากถ้าคุณจะต้องได้รับซอร์สโค้ดของไลบรารีที่ใดที่หนึ่งเพื่อรับเอกสารของ API


2
+1 - ด้วยการพิสูจน์ว่าแม้ว่าคุณจะใช้ Doxygen นั่นไม่ได้หมายความว่าคุณจะไม่อ่านจากแหล่งโดยตรงโดยตรง หมายเหตุประกอบของ Doxygen นั้นบางครั้งก็มีประโยชน์ในฐานะรูปแบบมาตรฐานที่ grep ใช้และเป็นประโยชน์ถ้าคำอธิบายประกอบที่คุณพบนั้นอยู่ใกล้กับรหัสที่อธิบายไว้
Steve314

1
@ Steve314 ofcourse ฉันไม่ได้บอกว่าคุณไม่เคยต้องการที่จะดูซอร์สโค้ดของบางไลบรารี - แต่นั่นจะไม่ใช่ที่แรกที่คุณจะมองหาว่า API มีลักษณะอย่างไรและจะใช้งานอย่างไร
Jesper

ฉันจะสนับสนุนให้ทุกอย่างที่เกี่ยวข้องกับ API ในส่วนหัว (หรืออย่างน้อยในส่วนหัวหรือแหล่งที่มา) เพราะมันจะหลีกเลี่ยงความไม่สอดคล้องกันที่อาจเกิดขึ้นเมื่ออัปเดตเอกสารในที่เดียวไม่ใช่ที่อื่น
jopasserat

12

เราแก้ไขปัญหานี้ (ประมาณ 25 ปีที่แล้ว) โดยการสร้าง #defines (เช่นสาธารณะส่วนตัว ฯลฯ ที่แก้ไขเป็น <ไม่มี>) ที่สามารถใช้ในไฟล์ต้นฉบับและถูกสแกนโดย awk script (น่ากลัว !) เพื่อสร้างไฟล์. h โดยอัตโนมัติ ซึ่งหมายความว่าความคิดเห็นทั้งหมดอาศัยอยู่ในแหล่งที่มาและถูกคัดลอก (ตามความเหมาะสม) ลงในไฟล์. h ที่สร้างขึ้น ฉันรู้ว่ามันเป็นโรงเรียนเก่า แต่มันทำให้เอกสารแบบอินไลน์แบบนี้ง่ายขึ้นอย่างมากมาย


1
อืมฉันรู้ว่ารูปแบบของสิ่งนี้จะมีประโยชน์ แต่จากมุมมองของฉันฉันมักจะพบว่าเอกสารประเภทนี้จะน่ารำคาญอย่างจริงจัง ...
osirisgothra

1
ในการถอดความ Donald Rumsfeld (ชายที่ฉันไม่ชอบ), "คุณเขียนโปรแกรมด้วยเครื่องมือที่คุณมีไม่ใช่เครื่องมือที่คุณต้องการให้มี" ทุกภาษาที่ฉันทำงานด้วยในช่วง 40 ปีที่ผ่านมามีหูดใหญ่อย่างน้อยหนึ่งแห่ง (ถ้าไม่มากกว่านั้น) โซลูชันของเราก) ทำงานข) เครื่องมือที่ใช้แล้วที่มีอยู่ในเวลานั้น c) ให้เราใช้เวลาของเราในการสร้างรหัสสร้างรายได้ออกนอกประตู
Peter Rowell

แม้ว่าฉันอาจจะไม่เลือกสิ่งนี้ แต่ก็เป็นวิธีที่น่าสนใจในการจัดการความคิดเห็นในส่วนหัว ส่วนหัวที่สร้างขึ้นจะอยู่ในการควบคุมเวอร์ชันหรือไม่ หรือนี่เป็นกระบวนการปล่อยบางอย่างสำหรับการสร้างแหล่งที่สามารถแจกจ่ายต่อได้? (แต่ไม่ได้ใช้โดยผู้พัฒนา)
คิด man42 42

โอ้ผมเคยเห็นรูปแบบเดียวกันในเร็ว ๆ นี้โครงการเริ่มต้นใน≥ 2000 และพวกเขาก็เพื่อความภาคภูมิใจของการประดิษฐ์ที่ฉลาดของพวกเขา ...
5gon12eder

3
ในกรณีของเราเราไม่ได้เก็บไฟล์ใด ๆ ที่สร้างขึ้นภายใต้การควบคุมเวอร์ชันเนื่องจากไฟล์เหล่านั้นเป็นไฟล์ที่ติดตามได้ง่ายและโดยตรง
Peter Rowell

9

สมมติว่านี่เป็นรหัสในโครงการขนาดใหญ่(ซึ่งนักพัฒนาจะย้ายระหว่างแหล่งที่มาและส่วนหัวบ่อย ๆ )และการให้สิ่งนี้ไม่ใช่ไลบรารี่ / มิดเดิลแวร์ซึ่งผู้อื่นอาจไม่สามารถเข้าถึงแหล่งที่มาได้ฉันพบว่างานนี้ ดีที่สุด ...

  • ส่วนหัว:
    แสดงความคิดเห็นสั้น ๆ 1-2 บรรทัดเฉพาะเมื่อจำเป็นเท่านั้น
    บางครั้งความคิดเห็นด้านบนกลุ่มของฟังก์ชันที่เกี่ยวข้องก็มีประโยชน์เช่นกัน
  • ที่มา:
    เอกสารเกี่ยวกับ API โดยตรงเหนือฟังก์ชั่น(ข้อความธรรมดาหรือ Doxygen ถ้าคุณต้องการ)
  • เก็บรายละเอียดการใช้งานเฉพาะที่เกี่ยวข้องกับนักพัฒนาที่แก้ไขโค้ดในเนื้อความของฟังก์ชัน

สาเหตุหลักของการทำเช่นนี้คือเพื่อเก็บความคิดเห็นไว้ใกล้กับรหัสฉันสังเกตเห็นว่าเอกสารในส่วนหัวมีแนวโน้มที่จะไม่ซิงค์กับการเปลี่ยนแปลงรหัสบ่อยขึ้น(แน่นอนพวกเขาไม่ควรทำ แต่พวกเขาทำในโครงการของเราที่ น้อย) นักพัฒนาอาจเพิ่มเอกสารที่ด้านบนของฟังก์ชั่นเมื่อพวกเขาทำการเปลี่ยนแปลงแม้ว่าจะมีเอกสารส่วนหัว ... ที่อื่น ทำให้เกิดข้อมูลซ้ำซ้อนหรือข้อมูลที่มีประโยชน์เฉพาะในหนึ่งในสตริงเอกสาร

แน่นอนคุณสามารถเลือกการประชุมและตรวจสอบให้แน่ใจว่า devs ติดตามทั้งหมดฉันเพิ่งพบการประชุมดังกล่าวข้างต้นเป็นธรรมชาติมากที่สุดและทำให้เกิดปัญหาน้อยที่สุดในการรักษา


ประการสุดท้ายสำหรับโครงการขนาดใหญ่ - มีความโน้มเอียงที่จะไม่ทำการแก้ไขเล็กน้อยในส่วนหัวเมื่อคุณรู้ว่ามันจะทำให้ไฟล์ 100 หรือ 1,000 อาจถูกคอมไพล์อีกครั้งเมื่อคนอื่นอัปเดตการควบคุมเวอร์ชัน - ชะลอข้อผิดพลาดเช่นกัน


5

ในความเห็นของฉัน (ค่อนข้าง จำกัด และลำเอียง) ฉันคิดว่าเป็นโปรซอร์สโค้ด เมื่อฉันทำบิตและชิ้นส่วนใน C ++ ฉันมักจะแก้ไขไฟล์ส่วนหัวหนึ่งครั้งและจากนั้นฉันไม่เคยกลับไปดูเลย

เมื่อฉันวางเอกสารในไฟล์ต้นฉบับฉันมักจะเห็นมันเสมอเมื่อฉันแก้ไขหรืออ่านรหัส ฉันคิดว่ามันเป็นเรื่องของนิสัย

แต่นั่นเป็นเพียงฉัน ...


1
ทำงานได้ไม่ดีนักหากสิ่งที่คุณมีคือไลบรารีที่คอมไพล์และไฟล์ส่วนหัว ในกรณีนี้ข้อมูลเพิ่มเติมในส่วนหัวเป็นสิ่งที่ดีเพราะเป็นเพียงเอกสารส่วนต่อประสานที่คุณมี
quick_now

คุณสามารถสร้างเอกสารด้วย doxygen - ใช้จากไฟล์. c เช่นกัน ดังนั้นคุณสามารถแจกจ่ายเอกสารได้อย่างง่ายดายด้วยห้องสมุดที่รวบรวม แต่ปัญหาจะเกิดขึ้นกับ IDE ที่สามารถแยกไฟล์ส่วนหัวและให้เอกสารกับคุณในขณะที่ใช้ฟังก์ชั่น ... แต่บางทีมันก็สามารถแก้สคริปต์การปรับใช้ซึ่งจะคัดลอกฟังก์ชั่นความคิดเห็น frm .c ลงใน. h ...
Vit Bernatik

5

ความคิดเห็นไม่ใช่เอกสารประกอบ โดยทั่วไปแล้วเอกสารสำหรับฟังก์ชั่นอาจเป็นข้อความ 2K หรืออาจเป็นไดอะแกรมดูตัวอย่างเอกสารสำหรับฟังก์ชั่นใน Windows SDK แม้ว่า comment-to-doc ของคุณจะอนุญาตสิ่งนี้คุณจะต้องสร้างรหัสที่มีความคิดเห็นที่อ่านไม่ได้ หากคุณต้องการผลิตเอกสารใช้ word-processor


อัปเดตเป็นเรื่องง่ายมากที่จะจัดทำเอกสารในวันนี้ (ที่มีสิ่งต่าง ๆ เช่นผู้สร้าง Qt ออกไปข้างนอก) เพื่อจัดทำเอกสารวิธี doxygen (หรือโคลน) ตัวอย่างเช่นใน qtc คุณเพิ่งกดปุ่ม / สองสามครั้ง ทำงานให้คุณแล้ว เนื่องจากสิ่งต่าง ๆ เช่นนี้ฉันสงสัยว่าคนจะต้องการข้ามไปยังโปรแกรมประมวลผลคำเพียงเพื่อบันทึกรหัสของพวกเขา ฉันเคยทำสิ่งนี้ได้รับอนุญาตในปี 2005 แต่ฉันจะไม่ทำเช่นนั้นในตอนนี้ แม้แต่การใช้โปรแกรมแก้ไข html ก็ดูเหมือนจะค่อนข้างคร่ำครึในตอนนี้
osirisgothra

@osirisgothra Doxygen- "เอกสาร" อาจทำได้ง่ายและแน่นอนว่าผลิต LOCs ที่เขียนขึ้นอย่างรวดเร็ว แต่มูลค่าของ "เอกสาร" ที่ผลิตยังคงเป็นที่โต้แย้งในกรณีส่วนใหญ่ ความคิดเห็นของ Doxygen นั้นไม่ใช่เอกสารที่ดีเลย (รายละเอียดที่สำคัญเกือบทั้งหมดหายไปอย่างเห็นได้ชัด) และพวกเขาก็ไม่ได้แสดงความคิดเห็นที่ดี ฉันคิดว่า nbt นั้นถูกต้องในการบอกว่าเอกสารจริงดีที่สุดไม่ผสมกับรหัสเพราะมันเป็นอันตรายต่อการอ่านรหัส มันจะไม่ซิงค์เลยไม่มีกระสุนเงินสำหรับสิ่งนั้น
cmaster

4

หากผู้มีส่วนได้ส่วนเสียของซอร์สโค้ดของคุณ (เช่นไลบรารีขนาดเล็ก) ประกอบด้วย "ผู้ใช้" (เพื่อนนักพัฒนาที่จะใช้ฟังก์ชั่นของห้องสมุดของคุณโดยไม่ต้องเกี่ยวข้องกับการนำไปใช้) และ "นักพัฒนา" (คุณและนักพัฒนาอื่น ๆ จากนั้นใส่ "ข้อมูลผู้ใช้" ในส่วนหัวและ "บันทึกการใช้งาน" ในแหล่งที่มา

เกี่ยวกับความปรารถนาที่จะไม่เปลี่ยนแปลงไฟล์ส่วนหัวเกินความจำเป็นอย่างยิ่ง - ฉันคิดว่าถ้าไลบรารี่ของคุณไม่ใช่ "ในการเปลี่ยนแปลงที่บ้า", "อินเตอร์เฟส" และ "functionarity" จะไม่เปลี่ยนแปลงมากนักและไม่ ความคิดเห็นส่วนหัวควรเปลี่ยนบ่อยเกินไป ในทางกลับกันความเห็นของซอร์สโค้ดจะต้องถูกซิงโครไนซ์ ("สด") กับซอร์สโค้ด


0

จุดรวมของการใช้ doxygen คือคุณสร้างเอกสารและทำให้สามารถเข้าถึงได้จากที่อื่น ตอนนี้เอกสารทั้งหมดในส่วนหัวเป็นเพียงขยะซึ่งทำให้ยากต่อการตรวจสอบการประกาศ funciton ที่จำเป็นได้อย่างรวดเร็วและอาจเกินพิกัด หนึ่งความคิดเห็นซับคือสูงสุดที่ควรไปที่นั่น แต่ถึงแม้จะเป็นการปฏิบัติที่ไม่ดี สาเหตุถ้าคุณเปลี่ยนเอกสารในแหล่งที่มาคุณทำการคอมไพล์แหล่งนั้นใหม่และเชื่อมโยงอีกครั้ง แต่ถ้าคุณใส่เอกสารไว้ในส่วนหัวคุณไม่ต้องการเปลี่ยนสิ่งเล็ก ๆ น้อย ๆ ในนั้นเพราะมันจะทำให้ส่วนสำคัญของโครงการสร้างใหม่


1
นี้ไม่ได้ดูเหมือนจะนำเสนออะไรที่สำคัญกว่าจุดทำและอธิบายในก่อน 7 คำตอบ
ริ้น

1
@gnat จาก 7 คำตอบก่อนหน้านี้มีเพียงคำตอบเดียวที่ให้รหัสกับส่วนหัว และอันนั้นก็ให้เหตุผลที่แตกต่างกันโดยสิ้นเชิง
สลาวา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.