กฎ“ as-if” คืออะไร?


90

ตามชื่อเรื่องว่า

กฎ "as-if" คืออะไร?

คำตอบทั่วไปที่เราจะได้รับคือ:

กฎที่อนุญาตให้มีการแปลงรหัสใด ๆ และทั้งหมดที่ไม่เปลี่ยนแปลงพฤติกรรมที่สังเกตได้ของโปรแกรม

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

หมายเหตุ: แท็กสิ่งนี้เป็น C และ C ++ ทั้งคู่เนื่องจากเกี่ยวข้องกับทั้งสองภาษา


2
มันหมายถึงเครื่องจักรที่เป็นนามธรรม
Alexey Frunze

" แท็กสิ่งนี้เป็น C และ C ++ ทั้งคู่เนื่องจากมีความเกี่ยวข้องกับทั้งสองภาษา " มีความเกี่ยวข้องในภาษาใดก็ได้
curiousguy

@AlexeyFrunze " มันหมายถึงเครื่องจักรที่เป็นนามธรรม " มันหมายถึงสถานะของ "เครื่องจักรที่เป็นนามธรรม" เป็นเครื่องมือและไม่ใช่จุดจบและไม่เกี่ยวข้องในแง่ของการปฏิบัติตามเนื่องจาก "นามธรรม" ซึ่งเป็นเครื่องมือที่กำหนดไม่ใช่ของจริง
curiousguy

คำตอบ:


100

กฎ " as-if " คืออะไร?

โดยพื้นฐานแล้วกฎ" as-if " จะกำหนดว่าการเปลี่ยนแปลงใดที่การใช้งานได้รับอนุญาตให้ดำเนินการในโปรแกรม C ++ ตามกฎหมาย ในระยะสั้นการเปลี่ยนแปลงทั้งหมดที่ไม่ส่งผลกระทบต่อ " พฤติกรรมที่สังเกตได้ " ของโปรแกรม(ดูคำจำกัดความที่ชัดเจนด้านล่าง) ได้รับอนุญาต

เป้าหมายคือเพื่อให้การใช้งานมีอิสระในการดำเนินการปรับให้เหมาะสมตราบเท่าที่พฤติกรรมของโปรแกรมยังคงเป็นไปตามความหมายที่กำหนดโดยมาตรฐาน C ++ ในแง่ของเครื่องจักรนามธรรม


มาตรฐานแนะนำกฎนี้ที่ไหน

มาตรฐาน C ++ 11 แนะนำกฎ " as-if " ในย่อหน้า 1.9 / 1:

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

นอกจากนี้เชิงอรรถอธิบายเพิ่มเติม:

ข้อกำหนดนี้บางครั้งเรียกว่ากฎ“ as-if”เนื่องจากการนำไปใช้มีอิสระที่จะเพิกเฉยต่อข้อกำหนดใด ๆ ของมาตรฐานสากลนี้ตราบใดที่ผลลัพธ์เป็นไปราวกับว่าข้อกำหนดนั้นได้รับการปฏิบัติตามเท่าที่สามารถกำหนดได้จากพฤติกรรมที่สังเกตได้ ของโปรแกรม ตัวอย่างเช่นการนำไปใช้งานจริงไม่จำเป็นต้องประเมินส่วนหนึ่งของนิพจน์หากสามารถอนุมานได้ว่าไม่ได้ใช้ค่าของมันและไม่มีผลข้างเคียงที่ส่งผลต่อพฤติกรรมที่สังเกตได้ของโปรแกรม


กฎบังคับว่าอย่างไร?

ย่อหน้าที่ 1.9 / 5 ระบุเพิ่มเติม:

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

เป็นเรื่องที่ควรค่าแก่การเน้นย้ำว่าข้อ จำกัด นี้มีผลเมื่อ"ดำเนินการโปรแกรมที่มีรูปแบบที่ดี"เท่านั้นและผลลัพธ์ที่เป็นไปได้ของการดำเนินการโปรแกรมที่มีพฤติกรรมที่ไม่ได้กำหนดนั้นไม่มีข้อ จำกัด มีการระบุไว้อย่างชัดเจนในย่อหน้าที่ 1.9 / 4 ด้วย:

การดำเนินการอื่น ๆ บางอย่างได้อธิบายไว้ในมาตรฐานสากลนี้ว่าไม่ได้กำหนดไว้ (ตัวอย่างเช่นผลของการพยายามแก้ไขวัตถุ const) [หมายเหตุ: มาตรฐานสากลนี้กำหนดความต้องการที่ไม่มีในลักษณะการทำงานของโปรแกรมที่มีพฤติกรรมที่ไม่ได้กำหนด - ส่งหมายเหตุ]

สุดท้ายเกี่ยวกับคำจำกัดความของ " พฤติกรรมที่สังเกตได้ " ย่อหน้าที่ 1.9 / 8 มีดังนี้:

ข้อกำหนดขั้นต่ำสำหรับการนำไปใช้งานที่สอดคล้องคือ:

- การเข้าถึงวัตถุระเหยได้รับการประเมินอย่างเคร่งครัดตามกฎของเครื่องจักรนามธรรม

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

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

เหล่านี้รวมกันจะเรียกว่าเป็นพฤติกรรมที่สังเกตได้ของโปรแกรม [ หมายเหตุ : การโต้ตอบที่เข้มงวดมากขึ้นระหว่างความหมายนามธรรมและความหมายที่แท้จริงอาจถูกกำหนดโดยการนำไปใช้ - หมายเหตุ ]


มีสถานการณ์ที่กฎนี้ใช้ไม่ได้หรือไม่?

จากความรู้ของฉันอย่างดีที่สุดข้อยกเว้นเดียวของกฎ " as-if " คือ copy / move elision ซึ่งได้รับอนุญาตแม้ว่าตัวสร้างการคัดลอกตัวสร้างการย้ายหรือตัวทำลายชั้นเรียนจะมีผลข้างเคียง เงื่อนไขที่แน่นอนสำหรับสิ่งนี้ระบุไว้ในย่อหน้าที่ 12.8 / 31:

เมื่อเกณฑ์ที่แน่นอนจะได้พบกับการดำเนินการที่ได้รับอนุญาตที่จะละเว้นการก่อสร้างคัดลอก / ย้ายของวัตถุชั้นแม้ว่าสร้างเลือกสำหรับการดำเนินการคัดลอก / ย้ายและ / หรือ destructor สำหรับวัตถุที่มีผลข้างเคียง [... ]


2
ฉันได้เห็นการอ้างอิงนี้ สิ่งที่ไม่ชัดเจนคือนิยามของพฤติกรรมที่สังเกตได้ อะไรที่มีคุณสมบัติเป็นพฤติกรรมที่สังเกตได้? การคัดลอก elision เป็นข้อยกเว้นของกฎ as-if นั้นค่อนข้างเป็นที่รู้จักกันดีและไม่ใช่ส่วนหนึ่งของคำถามของฉันจริงๆ
Alok Save

2
@AlokSave: ในมาตรฐาน C เราจะเห็น "การเข้าถึงวัตถุที่ระเหยได้การปรับเปลี่ยนวัตถุการแก้ไขไฟล์หรือการเรียกใช้ฟังก์ชันที่ดำเนินการใด ๆ เหล่านั้นล้วนเป็นผลข้างเคียง" น่าจะมีบางอย่างที่เทียบเท่าในมาตรฐาน C ++ ฉันเดาอย่างไม่เป็นทางการว่า "อะไรก็ตามที่เปลี่ยนแปลงปฏิสัมพันธ์กับโลกภายนอก"
Oliver Charlesworth

1
พฤติกรรมใด ๆ ที่เปลี่ยนสถานะของเครื่องนามธรรม (ดังนั้นบางสิ่งที่เปลี่ยนแปลงตัวแปรที่ส่งผ่านหรือตัวแปรส่วนกลางหรืออ่านและเขียนไปยังอุปกรณ์ I / O)
Mats Petersson

1
นี่หมายความว่าการลบลูปที่ไม่มีที่สิ้นสุดซึ่งไม่ได้รับอนุญาตตราบใดที่ไม่มีสิ่งใดเกิดขึ้นหลังจากนั้น?
harold

5
ประเด็นหนึ่งที่ควรทราบเป็นพิเศษคือใช้กับโปรแกรมทางกฎหมายเท่านั้น สิ่งใดก็ตามที่อ้างถึงพฤติกรรมที่ไม่ได้กำหนดไว้จะไม่อยู่ในความครอบคลุมใด ๆ อย่างชัดเจน
vonbrand

15

ใน C11 กฎจะไม่ถูกเรียกด้วยชื่อนั้น อย่างไรก็ตาม C เช่นเดียวกับ C ++ กำหนดพฤติกรรมในรูปแบบนามธรรม กฎ as-if อยู่ในC11 5.1.2.3p4 และ p6 :

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

  2. [... ]

  3. ข้อกำหนดขั้นต่ำสำหรับการนำไปใช้งานที่สอดคล้องคือ:

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

     

    นี่คือพฤติกรรมที่สังเกตได้ของโปรแกรม


-1

ในภาษา C, C ++, Ada, Java, SML ... ในภาษาการเขียนโปรแกรมใด ๆ ที่ระบุไว้อย่างดีโดยการอธิบายพฤติกรรม (โดยปกติจะเป็นไปได้หลายอย่างที่ไม่ได้กำหนด) ของโปรแกรม (ซึ่งแสดงให้เห็นถึงชุดการโต้ตอบบนพอร์ต I / O) , ไม่มีที่แตกต่างกันตามที่ถ้ากฎ

ตัวอย่างของกฎที่แตกต่างกันคือกฎที่ระบุว่าการหารด้วยศูนย์ทำให้เกิดข้อยกเว้น (Ada, Caml) หรือการแยกค่าเป็นโมฆะทำให้เกิดข้อยกเว้น (Java) คุณสามารถเปลี่ยนกฎเพื่อระบุอย่างอื่นและคุณจะลงท้ายด้วยภาษาอื่น (ซึ่งบางคนอยากจะเรียกว่า "ภาษาถิ่น" (*) มีกฎที่แตกต่างกันเพื่อระบุการใช้ภาษาโปรแกรมที่แตกต่างกันเช่นภาษาที่แตกต่างกัน กฎไวยากรณ์ครอบคลุมโครงสร้างไวยากรณ์บางส่วน

(*) ภาษาถิ่นตามนักภาษาศาสตร์บางคนเป็นภาษาที่มี "กองทัพ" ในบริบทนั้นอาจหมายถึงภาษาโปรแกรมที่ไม่มีคณะกรรมการและอุตสาหกรรมเฉพาะของบรรณาธิการคอมไพเลอร์

AS-ถ้ากฎไม่ได้เป็นกฎที่แตกต่างกัน ; มันไม่ครอบคลุมโปรแกรมใด ๆ โดยเฉพาะและไม่ใช่แม้แต่กฎที่สามารถพูดคุยลบหรือเปลี่ยนแปลงได้ แต่อย่างใดสิ่งที่เรียกว่า "กฎ" นั้นเป็นการย้ำว่ามีการกำหนดความหมายของโปรแกรมและสามารถพกพาได้เท่านั้น (โดยทั่วไป) กำหนดไว้ในแง่ของการโต้ตอบที่มองเห็นได้ของการดำเนินการของโปรแกรมกับโลก "ภายนอก"

โลกภายนอกสามารถเป็นอินเทอร์เฟซ I / O (stdio), GUI หรือแม้แต่ล่ามเชิงโต้ตอบที่ส่งออกค่าผลลัพธ์ของภาษาประยุกต์ที่แท้จริง ใน C และ C ++ รวมถึงการเข้าถึงวัตถุระเหย (ระบุอย่างคลุมเครือ) ซึ่งเป็นอีกวิธีหนึ่งในการบอกว่าวัตถุบางอย่าง ณ จุดที่กำหนดจะต้องแสดงในหน่วยความจำอย่างเคร่งครัดตาม ABI (Application Binary Interface) โดยไม่ต้องกล่าวถึง ABI อย่างชัดเจน

คำจำกัดความของสิ่งที่เป็นร่องรอยของการดำเนินการเรียกอีกอย่างว่าพฤติกรรมที่มองเห็นได้หรือสังเกตได้จะกำหนดความหมายของ "กฎ as-if" กฎ as-if พยายามอธิบาย แต่การทำเช่นนั้นจะทำให้ผู้คนสับสนมากกว่าที่จะชี้แจงสิ่งต่าง ๆ เนื่องจากมันให้การแสดงออกของการเป็นกฎเชิงความหมายเพิ่มเติมที่ให้โอกาสในการใช้งานมากขึ้น

สรุป:

  • สิ่งที่เรียกว่า "as-if rule" ไม่ได้ผ่อนคลายข้อ จำกัด ใด ๆ ในการนำไปใช้งาน
  • คุณไม่สามารถลบกฎ as-if ในภาษาโปรแกรมใด ๆ ที่ระบุในเงื่อนไขของพฤติกรรมที่มองเห็นได้ (การติดตามการดำเนินการประกอบด้วยสำหรับการโต้ตอบกับโลกภายนอก) เพื่อให้ได้ภาษาถิ่นที่แตกต่างกัน
  • คุณไม่สามารถเพิ่มกฎ as-if ในภาษาโปรแกรมใด ๆ ที่ไม่ได้ระบุไว้ในเงื่อนไขของลักษณะการทำงานที่มองเห็นได้

ถ้าผู้คนเชื่อว่าฉันผิดและมี "กฎ" ที่แตกต่างกันทำไมพวกเขาไม่พยายามอธิบายรูปแบบของ C ++ (ภาษาถิ่น) ที่ไม่มี "กฎ" ข้อกำหนด C ++ หมายความว่าอย่างไรโดยไม่มีมัน คงเป็นไปไม่ได้อย่างแน่นอนที่จะบอกได้ว่าคอมไพเลอร์สอดคล้องกันหรือไม่ หรือแม้แต่กำหนดความสอดคล้อง
ซอกแซก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.