สิ่งนี้เริ่มต้นจากคำถาม SO แต่ฉันรู้ว่ามันค่อนข้างแปลกใหม่และตามคำอธิบายที่แท้จริงบนเว็บไซต์มันอาจจะเหมาะกว่าสำหรับ programmers.se เนื่องจากคำถามมีน้ำหนักเชิงแนวคิดจำนวนมาก
ฉันได้เรียนรู้เสียงดังกังวาน LibToolingและเป็นเครื่องมือที่มีประสิทธิภาพมากที่สามารถเปิดเผย "nitty gritty" ทั้งหมดของรหัสด้วยวิธีที่เป็นมิตรกล่าวคือในทางที่เป็นความหมายและไม่ต้องเดาด้วยเช่นกัน ถ้าเสียงดังกราวสามารถรวบรวมรหัสของคุณแล้วเสียงดังกราวเป็นบางอย่างเกี่ยวกับความหมายของตัวละครทุกตัวเดียวภายในรหัสว่า
ตอนนี้ให้ฉันถอยกลับสักครู่
มีปัญหาในทางปฏิบัติมากมายที่เกิดขึ้นเมื่อมีคนเข้าร่วมในเทมเพลต metaprogramming เทมเพลต C ++ (และโดยเฉพาะอย่างยิ่งเมื่อมีการใช้เทมเพลตเกินกว่าเทมเพลตเข้าไปในอาณาเขตของมาโครที่ชาญฉลาด ตามจริงแล้วสำหรับโปรแกรมเมอร์หลาย ๆ คนรวมถึงตัวเองการใช้งานเทมเพลตทั่วไปจำนวนมากก็ค่อนข้างน่ากลัวเช่นกัน
ผมคิดว่าเป็นตัวอย่างที่ดีจะเป็นสตริงเวลารวบรวม นี่เป็นคำถามที่มีอายุเกินหนึ่งปีแล้ว แต่เป็นที่ชัดเจนว่า C ++ ณ ตอนนี้ไม่ได้ทำให้เป็นเรื่องง่ายสำหรับมนุษย์ปุถุชน ในขณะที่ดูตัวเลือกเหล่านี้ยังไม่เพียงพอที่จะทำให้เกิดอาการคลื่นไส้สำหรับฉัน แต่ก็ทำให้ฉันไม่มั่นใจเกี่ยวกับความสามารถในการสร้างรหัสเครื่องจักรที่มีประสิทธิภาพและมีประสิทธิภาพสูงสุดเพื่อให้เหมาะกับแอปพลิเคชันแฟนซีที่ฉันมีสำหรับซอฟต์แวร์ของฉัน
ฉันหมายความว่าเรามาเจอกันคนอื่น ๆ สตริงนั้นค่อนข้างเรียบง่ายและเรียบง่าย พวกเราบางคนแค่ต้องการวิธีที่สะดวกในการปล่อยรหัสเครื่องที่มีสตริง "อบใน" อย่างมีนัยสำคัญมากกว่าที่เราจะได้รับเมื่อทำการเข้ารหัสในลักษณะที่ตรงไปตรงมา ในรหัส C ++ ของเรา
ป้อน clang และ LibTooling ซึ่งแสดงแผนผังต้นไม้นามธรรม (AST) ของซอร์สโค้ดและอนุญาตให้แอปพลิเคชัน C ++ แบบกำหนดเองอย่างง่าย ๆ สามารถจัดการกับซอร์สโค้ดดิบ (ใช้Rewriter
) อย่างถูกต้องและเชื่อถือได้พร้อมกับโมเดลเชิงวัตถุเชิงความหมาย มันจัดการกับสิ่งต่าง ๆ มากมาย มันรู้เกี่ยวกับการขยายมาโครและช่วยให้คุณติดตามกลุ่มเหล่านั้นได้ ใช่ฉันกำลังพูดถึงการแปลงหรือการแปลซอร์สโค้ด
วิทยานิพนธ์ขั้นพื้นฐานของฉันที่นี่คือเสียงดังกราวทำให้เราสามารถสร้างโปรแกรมเรียกใช้งานที่พวกเขาสามารถทำหน้าที่เป็นตัวประมวลผลล่วงหน้าแบบกำหนดเองที่เหมาะกับซอฟต์แวร์ C ++ ของเราและเราสามารถใช้ขั้นตอน เราถูก จำกัด ด้วยความจริงที่ว่าขั้นตอนนี้จะต้องรับอินพุตซึ่งเป็นรหัส C ++ ที่ถูกต้องและสร้างเป็นรหัส C ++ ที่ถูกต้องมากขึ้น รวมถึงข้อ จำกัด อื่น ๆ ที่ระบบการสร้างของคุณใช้
การป้อนข้อมูลจะต้องใกล้เคียงกับรหัส C ++ ที่ถูกต้องอย่างน้อยที่สุดเพราะหลังจากนั้นเสียงดังกราวคือคอมไพเลอร์ฟรอนต์เอนด์และเราเพียงแค่พูดเล่น ๆ และสร้างสรรค์ด้วย API ของมัน ฉันไม่ทราบว่ามีข้อกำหนดใด ๆ สำหรับความสามารถในการกำหนดไวยากรณ์ใหม่ที่จะใช้ แต่ชัดเจนว่าเราต้องพัฒนาวิธีในการแยกวิเคราะห์อย่างถูกต้องและเพิ่มลงในโครงการเสียงดังกราวเพื่อทำสิ่งนี้ การคาดหวังอีกต่อไปคือการมีบางสิ่งในโครงการเสียงดังกราวที่อยู่นอกขอบเขต
ไม่ใช่ปัญหา. ฉันนึกภาพว่าฟังก์ชั่นมาโครที่ไม่มี op บางตัวสามารถจัดการงานนี้ได้
อีกวิธีหนึ่งในการดูสิ่งที่ฉันอธิบายคือการนำ metaprogramming constructs ไปใช้โดยใช้ runtime C ++ ด้วยการจัดการ AST ของซอร์สโค้ดของเรา (ขอบคุณ clang และ API) แทนที่จะใช้มันโดยใช้เครื่องมือที่ จำกัด มากขึ้นในภาษาของตัวเอง สิ่งนี้มีประโยชน์ด้านประสิทธิภาพการคอมไพล์ที่ชัดเจนเช่นกัน (ส่วนหัวเทมเพลต - หนักการรวบรวมช้าลงตามสัดส่วนที่คุณใช้บ่อย ๆ สิ่งที่รวบรวมไว้จำนวนมากจากนั้นจะถูกจับคู่อย่างระมัดระวังและทิ้งโดยลิงเกอร์)
อย่างไรก็ตามสิ่งนี้มีค่าใช้จ่ายในการแนะนำขั้นตอนเพิ่มเติมหรือสองขั้นตอนในกระบวนการสร้างและในความต้องการของการเขียนซอฟต์แวร์ verbose ค่อนข้างมาก (เป็นที่ยอมรับ) (อย่างน้อยก็ตรงไปตรงมา runtime C ++) เป็นส่วนหนึ่งของเครื่องมือของเรา .
นั่นไม่ใช่ภาพรวมทั้งหมด ฉันค่อนข้างมั่นใจว่ามีช่องว่างขนาดใหญ่กว่าของฟังก์ชันการทำงานที่สามารถเกิดขึ้นได้จากการสร้างรหัสที่ยากมากหรือเป็นไปไม่ได้ด้วยคุณสมบัติภาษาหลัก ใน C ++ คุณสามารถเขียนเทมเพลตหรือมาโครหรือการรวมกันอย่างบ้าคลั่งของทั้งคู่ แต่ในเครื่องมือ clang คุณสามารถปรับเปลี่ยนคลาสและฟังก์ชั่นด้วยวิธีใดก็ได้ที่คุณสามารถทำได้ด้วย C ++ ที่รันไทม์ในขณะที่เข้าถึงเนื้อหาเชิงความหมายนอกจากเทมเพลตและมาโครและทุกอย่างอื่นแล้ว
ดังนั้นฉันสงสัยว่าทำไมทุกคนไม่ได้ทำเช่นนี้ ฟังก์ชั่นนี้จาก clang นั้นใหม่และไม่มีใครคุ้นเคยกับ AST ของ clang ในระดับชั้นเรียนขนาดใหญ่? ไม่สามารถทำได้
บางทีฉันอาจจะประเมินความยากของเรื่องนี้เล็กน้อย แต่การทำ "การจัดการสตริงเวลารวบรวม" ด้วยเครื่องมือเสียงดังกราวอาจเป็นเรื่องง่าย มัน verbose แต่ตรงไปตรงมาเมามัน สิ่งที่จำเป็นทั้งหมดคือฟังก์ชั่นมาโครที่ไม่ต้องใช้งานซึ่งแมปกับstd::string
การใช้งานจริง ปลั๊กอินเสียงดังกราวใช้ส่วนนี้โดยดึงมาโครที่ไม่มีการเรียกแมโครที่เกี่ยวข้องทั้งหมดและทำการดำเนินการกับสตริง เครื่องมือนี้จะถูกแทรกเป็นส่วนหนึ่งของกระบวนการสร้าง ในระหว่างการสร้างการเรียกฟังก์ชันแมโคร no-op เหล่านี้จะถูกประเมินโดยอัตโนมัติในผลลัพธ์แล้วแทรกกลับเป็นสตริงการคอมไพล์เวลาเก่าแบบธรรมดาในโปรแกรม โปรแกรมสามารถคอมไพล์ได้ตามปกติ ในความเป็นจริงโปรแกรมที่เป็นผลลัพธ์นี้ยังพกพาได้มากขึ้นโดยไม่ต้องใช้คอมไพเลอร์ตัวใหม่ที่รองรับ C ++ 11