จำเป็นหรือไม่ที่จะต้องปฏิบัติตามมาตรฐานใช้มาตรฐาน C สำหรับเรื่องนั้น?


17

มีบางคนที่มีประสบการณ์มากใน Stack Overflow ที่พูดถึงมาตรฐาน C เสมอ ผู้คนดูเหมือนจะไม่ชอบโซลูชันที่ไม่สามารถพกพาได้แม้ว่าพวกเขาจะทำงานให้ฉันก็ตาม ตกลงฉันเข้าใจว่าต้องปฏิบัติตามมาตรฐาน แต่ไม่ได้ใส่ความคิดสร้างสรรค์ของโปรแกรมเมอร์หรือไม่

อะไรคือประโยชน์ที่เป็นรูปธรรมที่มาจากการทำตามมาตรฐาน? โดยเฉพาะอย่างยิ่งเนื่องจากคอมไพเลอร์อาจใช้มาตรฐานแตกต่างกันเล็กน้อย


7
คุณช่วยอธิบายความหมายของ "มาตรฐาน" ได้ไหม? คุณหมายถึงไม่เข้าใจพฤติกรรมที่ไม่ได้กำหนดโดยมาตรฐานหรือไม่? หรือไม่ใช้คุณสมบัติส่วนขยาย / คอมไพเลอร์? หรือสไตล์การประชุม?
ikh

1
@ikh เขากำลังดำเนินการเกี่ยวกับมาตรฐาน ISO C (C90, C99, C11)
Aseem Bansal

9
นั่นเหมือนกับการพูดว่าการเขียนหรือการพูดภาษาอังกฤษโดยใช้ไวยากรณ์และคำศัพท์ภาษาอังกฤษทำให้คุณมีความคิดสร้างสรรค์ แน่นอนว่าผู้คนสามารถทำสิ่งที่ยอดเยี่ยมโดยการทำผิดกฎค่าใช้จ่ายในการเชื่อมโยงกัน แต่คุณสามารถเขียนหนังสือสร้างสรรค์ได้หลายล้านเล่มในขณะที่ยังคงยึดมั่นใน "มาตรฐาน" ของภาษาอังกฤษ
Avner Shahar-Kashtan

คุณสามารถเพิ่มตัวอย่างของ "คนดูเหมือนจะไม่ชอบโซลูชันที่ไม่สามารถพกพาได้แม้ว่าพวกเขาจะทำงานให้ฉัน"?
BЈовић

1
@PHIfounder เพียงเพื่อจัดการกับกรณีที่ผ่านมาคุณสามารถละเว้นการกลับมาจากหลักได้โดยปริยายคืน 0 :)
Daniel Gratzer

คำตอบ:


45

มีเหตุผลบางประการที่การยึดมาตรฐานเป็นสิ่งที่ดี

  1. การถูกล็อคเข้ากับคอมไพเลอร์นั้นยากมาก คุณอยู่ในความเมตตาของกลุ่มนักพัฒนาที่มีวาระของตัวเอง เห็นได้ชัดว่าไม่ได้ออกมาให้คุณหรืออะไรเลย แต่ถ้าคอมไพเลอร์ของคุณเริ่มล้าหลังในการปรับแต่งคุณสมบัติใหม่การแก้ไขความปลอดภัย ฯลฯ แย่มาก; คุณติดอยู่ ในกรณีที่รุนแรง บริษัท บางแห่งจำเป็นต้องเริ่มการปะแก้เครื่องมือใด ๆ ที่ทำให้พวกเขาต้องพึ่งพาตนเอง นี่คือเงินและเวลาที่เสียไปอย่างมากเมื่อมีเครื่องมือทำงานอื่น ๆ อยู่ที่นั่น

  2. การถูกล็อคเข้าสู่แพลตฟอร์มนั้นยากขึ้น หากคุณกำลังผลักดันซอฟต์แวร์บน Linux และต้องการเปลี่ยนมาใช้ Windows เพราะคุณรู้ว่าตลาดของคุณอยู่ที่นั่นคุณจะต้องใช้เวลาในการเปลี่ยนแฮ็คแบบพกพาที่คุณมีในรหัสเพื่อเล่นเกม ด้วย GCC และ MSVC หากคุณมีการออกแบบหลักของคุณหลายชิ้นโดยยึดตามสิ่งนั้นโชคดี!

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

ดังนั้นข้อความเอาชนะที่นี่ติดกับมาตรฐานที่ทำให้คุณมีความยืดหยุ่นมากขึ้น คุณมีภาษาที่ จำกัด มากขึ้น แต่คุณมีมากขึ้น

  • ห้องสมุด
  • การสนับสนุน (ผู้รู้มาตรฐานไม่ใช่แฮ็คเฉพาะคอมไพเลอร์ที่สลับซับซ้อน)
  • แพลตฟอร์มที่มีอยู่
  • เครื่องมือสำหรับผู้ใหญ่
  • ความปลอดภัย (การพิสูจน์ในอนาคต)

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


+1 ยุติธรรมพอ :) ขอบคุณ ... ฉันสับสนอย่างจริงจังกับวิธีที่คอมไพเลอร์เบี่ยงเบนจากมาตรฐานเล็กน้อยและทำให้ฉันรู้สึกสงสัยเกี่ยวกับการติดตามอย่างเคร่งครัดจำเป็นต้องรู้ข้อดีและข้อเสียของมันและคุณระบุอย่างชัดเจน
0

6
พฤติกรรมที่ไม่ได้กำหนดอาจจะดูดบิตเช่นกัน ถ้าคุณไม่ปฏิบัติตามมาตรฐานอย่างใกล้ชิดคุณสามารถคบกับ UB ได้อย่างง่ายดาย
CodesInChaos

@CodesInChaos ตกลงไม่ได้กำหนดพฤติกรรมเป็นที่ดีบนมือข้างหนึ่งเพราะมันช่วยให้การเพิ่มประสิทธิภาพบางบ้า แต่ในการแก้จุดบกพร่องอื่น ๆ มัน ...
แดเนียล Gratzer

6

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

ดังนั้นอะไรคือข้อดีของการทำตามมาตรฐานมากกว่าแบบจำลองทางจิตของคุณเอง?

พูดง่ายๆคือมาตรฐานนั้นถูกต้องและแบบจำลองทางจิตของคุณเองผิด แบบจำลองทางจิตของคุณมักจะเป็นมุมมองที่เรียบง่ายเกี่ยวกับการทำงานของสิ่งต่าง ๆ ในระบบของคุณในกรณีทั่วไปโดยการปิดใช้งานการปรับแต่งคอมไพเลอร์ทั้งหมด ผู้ขายคอมไพเลอร์โดยทั่วไปไม่ได้พยายามที่จะปฏิบัติตามโดยเฉพาะอย่างยิ่งเมื่อมันมาถึงการเพิ่มประสิทธิภาพ (หากคุณไม่ทำตามสัญญาจนสิ้นสุดคุณไม่สามารถคาดหวังพฤติกรรมที่เฉพาะเจาะจงจากคอมไพเลอร์: ขยะเข้าและขยะออก)

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

มันอาจจะเป็นการดีกว่าถ้าจะพูดว่า "แม้ว่าพวกเขาจะทำงานให้ฉัน" เว้นแต่ว่าคอมไพเลอร์เอกสารเฉพาะของคุณที่พฤติกรรมที่กำหนดจะทำงาน (นั่นคือ: ถ้าคุณกำลังใช้มาตรฐานที่ได้รับการตกแต่งแล้วซึ่งประกอบด้วยเอกสารมาตรฐานที่เหมาะสมพร้อมกับคอมไพเลอร์) คุณไม่ทราบว่ามันใช้งานได้จริงหรือเชื่อถือได้จริง ๆ ตัวอย่างเช่นโดยทั่วไปจำนวนเต็มล้นลงนามผลในห่อในหลาย ๆ ระบบ (ดังนั้นINT_MAX+1เป็นปกติINT_MIN) - ยกเว้นว่าคอมไพเลอร์ "รู้" ว่าเลขจำนวนเต็มที่ลงนามไม่เคยล้นในโปรแกรม C (ถูกต้อง) และมักจะทำการเพิ่มประสิทธิภาพที่น่าแปลกใจมากบนพื้นฐานนี้ " ความรู้"


1
คุณสามารถคอมไพล์ด้วย-fwrapvและจากนั้นคุณกำลังใช้ภาษาที่ไม่ได้มาตรฐานแตกต่างกันเล็กน้อยที่เลขจำนวนเต็มที่ลงนามแล้วจะล้อมรอบเสมอ
user253751

@immibis: เมื่อ C89 ถูกเขียนตามเอกสารเหตุผลของมันคอมไพเลอร์ร่วมสมัยส่วนใหญ่ได้นิยามซีแมนทิกส์แบบเงียบสำหรับการล้นจำนวนเต็ม ในหลายกรณีการมีการค้ำประกันบางประเภทเกี่ยวกับสิ่งที่เกิดขึ้นในกรณีที่จำนวนเต็มมากเกินอาจทำให้โค้ดมีประสิทธิภาพมากกว่าที่จะเป็นไปได้หากไม่มีการค้ำประกันดังกล่าวโดยเฉพาะอย่างยิ่งหากการค้ำประกันไม่ได้ไปไกล พฤติกรรมการห่อสามารถเลียนแบบได้โดยใช้คณิตศาสตร์ที่ไม่ได้ลงนาม แต่ความหมายซึ่งหลวม แต่ยังเพียงพอที่จะทำตามข้อกำหนดอาจทำให้โค้ดมีประสิทธิภาพมากขึ้น]
supercat

@immibis: มันเลวร้ายเกินไปที่ผู้แก้ไขใหม่สามารถโน้มน้าวผู้คนได้ว่าพฤติกรรมที่นำมาใช้อย่างเป็นเอกฉันท์ในบรรดาคอมไพเลอร์สำหรับแพลตฟอร์มบางแห่ง (หรือในบางกรณี 100% เป็นเอกฉันท์) ไม่เคยมี "มาตรฐาน" บนแพลตฟอร์มดังกล่าว การสูญเสียประสิทธิภาพอันเป็นผลมาจากการหลีกเลี่ยงพฤติกรรมดังกล่าวจะไม่ถูกชดเชยด้วย "การเพิ่มประสิทธิภาพ" ใด ๆ ที่ผู้แปลสามารถทำได้โดยการเพิกถอน
supercat

4

ฉันเข้าใจว่าต้องมีการปฏิบัติตามมาตรฐาน แต่มันไม่ได้ทำให้ความคิดสร้างสรรค์ของโปรแกรมเมอร์เป็นปัญหาหรือ? ยังคงมีความแตกต่างบางประการในการที่คอมไพเลอร์ต่างกันปฏิบัติตามมาตรฐาน ตัวอย่างเช่นฉันสามารถเขียนโค้ดที่ใช้งานได้ดีมากในด้านประสิทธิภาพและความเร็วเช่นทั้งหมดที่มีความสำคัญ แต่ก็ยังอาจไม่จำเป็นต้องปฏิบัติตามมาตรฐานอย่างเคร่งครัด

ไม่มาตรฐานบอกสิ่งที่ได้รับอนุญาตให้ทำ หากไม่ได้ระบุไว้คุณอยู่ในขอบเขตพฤติกรรมที่ไม่ได้กำหนดและการเดิมพันทั้งหมดจะปิด - โปรแกรมมีอิสระที่จะทำอะไรก็ได้


เมื่อคุณพูดถึงตัวอย่างเฉพาะของvoid main()vs int main()ฉันสามารถปรับปรุงคำตอบของฉัน

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

ในทางกลับกันมาตรฐานกำหนดลายเซ็นของหลักอย่างชัดเจนint main()และจะบอกสิ่งที่ควรทำ


ในทางตรงกันข้ามมีสิ่งที่ไม่ได้กำหนดไว้ในมาตรฐาน จากนั้นอาจใช้มาตรฐานอื่น (เช่น POSIX) ตัวอย่างที่ดีที่สุดอาจเกิดจากการใช้เธรดใน c ++ 03 เนื่องจากโปรแกรมมาตรฐาน c ++ 03 เป็น 1-threaded ในกรณีที่คุณถูกบังคับให้ใช้แพลตฟอร์มห้องสมุดขึ้นหรือสิ่งที่ต้องการเพิ่ม


4
ทุกสิ่งที่คอมไพเลอร์ทำนั้นไม่ได้เป็นมาตรฐานไม่ใช่พฤติกรรมที่ไม่ได้กำหนดไว้ แต่ส่วนขยายของคอมไพเลอร์นั้นได้รับการกำหนดไว้อย่างดีในแง่ที่ว่าพวกเขามีความมุ่งมั่นและตั้งใจ ไม่ใช่ UB
Daniel Gratzer

@jozefg วิธีที่ถูกถาม - เป็นที่ชัดเจนว่า OP คิดว่าวิธี UB ของการดำเนินการ ตัวอย่างเช่นเธรดไม่ได้ถูกกำหนดใน c ++ 03
BЈовић

1
@deworde: ความคิดเห็นถูกลบออกจากคำตอบ
Kevin

@jozefg หากคอมไพเลอร์โดยเฉพาะห่อจำนวนเต็มลงนามก็อาจถือว่าเป็นส่วนขยายของภาษาที่ไม่มีเอกสาร (แน่นอนว่าการไม่มีเอกสารหมายถึงคุณไม่รับประกันว่าจะไม่ลบส่วนขยาย)
253751

-6

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


2
คำตอบนี้อาจไร้ประโยชน์ในกรณีที่คนอื่นโพสต์ความคิดเห็นตรงข้ามโดยไม่มีคำอธิบาย ตัวอย่างเช่นหากมีคนโพสต์การอ้างสิทธิ์เช่น"ทำตามกฎถ้าโครงการของคุณเกี่ยวกับโครงการพิเศษเช่นโครงการรัฐบาลหรือกองทัพบก แต่คุณไม่จำเป็นต้องปฏิบัติตามกฎหากคุณกำลังพูดถึงโอเพ่นซอร์ส ... "คำตอบนี้จะช่วยให้ผู้อ่านเลือกความคิดเห็นที่คัดค้านสองเรื่องได้อย่างไร ลองพิจารณาการแก้ไขให้ดีขึ้น
ริ้น

2
Uknown: คุณต้องการจะประหลาดใจที่จะเรียนรู้วิธีการหลายมาตรฐานที่มีอยู่ในโครงการ gov ...
Deer Hunter
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.