พฤติกรรมที่ไม่ได้กำหนดใน C และ C ++ คืออะไร สิ่งที่เกี่ยวกับพฤติกรรมที่ไม่ระบุและพฤติกรรมที่กำหนดไว้ในการนำไปใช้ ความแตกต่างระหว่างพวกเขาคืออะไร?
พฤติกรรมที่ไม่ได้กำหนดใน C และ C ++ คืออะไร สิ่งที่เกี่ยวกับพฤติกรรมที่ไม่ระบุและพฤติกรรมที่กำหนดไว้ในการนำไปใช้ ความแตกต่างระหว่างพวกเขาคืออะไร?
คำตอบ:
พฤติกรรมที่ไม่ได้กำหนดเป็นหนึ่งในแง่มุมของภาษา C และ C ++ ที่น่าแปลกใจที่โปรแกรมเมอร์ที่มาจากภาษาอื่น (ภาษาอื่นพยายามซ่อนมันให้ดีขึ้น) โดยพื้นฐานแล้วเป็นไปได้ที่จะเขียนโปรแกรม C ++ ที่ไม่ทำงานในลักษณะที่คาดเดาได้แม้ว่าคอมไพเลอร์ C ++ หลายรายจะไม่รายงานข้อผิดพลาดใด ๆ ในโปรแกรม!
ลองดูตัวอย่างคลาสสิก:
#include <iostream>
int main()
{
char* p = "hello!\n"; // yes I know, deprecated conversion
p[0] = 'y';
p[5] = 'w';
std::cout << p;
}
ตัวแปรp
ชี้ไปที่ตัวอักษรของสตริง"hello!\n"
และการมอบหมายสองรายการด้านล่างพยายามแก้ไขสตริงตัวอักษรนั้น โปรแกรมนี้ทำอะไร ตามมาตรา 2.14.5 วรรค 11 ของมาตรฐาน C ++ จะเรียกใช้การทำงานที่ไม่ได้กำหนด :
ผลของการพยายามแก้ไขสตริงตัวอักษรจะไม่ได้กำหนด
ฉันได้ยินเสียงคนกรีดร้อง "แต่เดี๋ยวก่อนฉันสามารถรวบรวมสิ่งนี้ได้โดยไม่มีปัญหาและรับเอาต์พุตyellow
" หรือ "คุณหมายถึงสิ่งที่ไม่ได้กำหนดตัวอักษรสตริงจะถูกเก็บไว้ในหน่วยความจำแบบอ่านอย่างเดียวดังนั้นความพยายามในการมอบหมายครั้งแรก นี่เป็นปัญหาที่เกิดขึ้นกับพฤติกรรมที่ไม่ได้กำหนด โดยทั่วไปมาตรฐานจะอนุญาตให้มีสิ่งใดเกิดขึ้นเมื่อคุณเรียกใช้พฤติกรรมที่ไม่ได้กำหนด (แม้แต่ปีศาจทางจมูก) หากมีพฤติกรรม "ถูกต้อง" ตามโมเดลจิตของภาษาของคุณโมเดลนั้นก็ผิด มาตรฐาน C ++ มีเพียงการลงคะแนนระยะเวลา
ตัวอย่างอื่น ๆ ของพฤติกรรมที่ไม่ได้กำหนดรวมถึงการเข้าถึงอาร์เรย์เกินขอบเขตของมัน, dereferencing ชี้โมฆะ , การเข้าถึงวัตถุหลังจากที่ชีวิตของพวกเขาจบลงหรือเขียนสำนวนที่ถูกกล่าวหาว่าฉลาดi++ + ++i
เช่น
มาตรา 1.9 ของ C ++ มาตรฐานยังกล่าวถึงไม่ได้กำหนดพฤติกรรมของพี่ชายสองคนที่อันตรายน้อยกว่าพฤติกรรมที่ไม่ระบุและพฤติกรรมการดำเนินงานที่กำหนดไว้ :
คำอธิบายความหมายในมาตรฐานสากลนี้กำหนดเครื่องนามธรรมที่เป็นพารามิเตอร์
บางแง่มุมและการทำงานของเครื่องนามธรรมมีการอธิบายไว้ในมาตรฐานสากลนี้ตามที่กำหนดไว้ในการนำไปใช้ (ตัวอย่างเช่น
sizeof(int)
) สิ่งเหล่านี้เป็นพารามิเตอร์ของเครื่องนามธรรม การใช้งานแต่ละครั้งจะต้องมีเอกสารอธิบายลักษณะและพฤติกรรมของตนในส่วนที่เกี่ยวข้องแง่มุมอื่น ๆ และการทำงานของเครื่องนามธรรมมีการอธิบายไว้ในมาตรฐานสากลนี้ว่าไม่ได้รับการระบุ (ตัวอย่างเช่นลำดับของการประเมินผลการขัดแย้งกับฟังก์ชั่น) หากเป็นไปได้มาตรฐานสากลนี้จะกำหนดชุดของพฤติกรรมที่อนุญาต สิ่งเหล่านี้กำหนดแง่มุมที่ไม่ต่อเนื่องของเครื่องนามธรรม
การดำเนินการอื่น ๆ บางอย่างมีการอธิบายไว้ในมาตรฐานสากลนี้ว่าไม่ได้กำหนด (ตัวอย่างเช่นผลกระทบของการยกเลิกการอ้างอิงตัวชี้โมฆะ) [ หมายเหตุ : มาตรฐานสากลนี้ไม่มีข้อกำหนดเกี่ยวกับพฤติกรรมของโปรแกรมที่มีพฤติกรรมที่ไม่ได้กำหนด - บันทึกท้าย ]
โดยเฉพาะอย่างยิ่งส่วน 1.3.24 ฯ :
พฤติกรรมที่ไม่ได้กำหนดอนุญาตช่วงจากการละเว้นสถานการณ์อย่างสมบูรณ์กับผลลัพธ์ที่ไม่สามารถคาดการณ์ได้ถึงพฤติกรรมในระหว่างการแปลหรือการดำเนินการโปรแกรมในลักษณะเอกสารของสภาพแวดล้อม (มีหรือไม่มีการออกข้อความวินิจฉัย) เพื่อยกเลิกการแปลหรือการดำเนินการ ของข้อความวินิจฉัย)
คุณจะทำอย่างไรเพื่อหลีกเลี่ยงพฤติกรรมที่ไม่ได้กำหนด โดยทั่วไปคุณต้องอ่านหนังสือC ++ ที่ดีโดยผู้แต่งที่รู้ว่าพวกเขากำลังพูดถึงอะไร สกรูบทเรียนอินเทอร์เน็ต สกรู bullschildt
int f(){int a; return a;}
: ค่าa
อาจเปลี่ยนแปลงระหว่างการเรียกใช้ฟังก์ชัน
ทีนี้นี่คือการคัดลอกวางตรงจากมาตรฐาน
3.4.1 1 พฤติกรรมที่กำหนดโดยการนำไปใช้งานไม่ได้ระบุพฤติกรรมที่แต่ละเอกสารการนำไปปฏิบัติจะมีวิธีการเลือกอย่างไร
2 ตัวอย่างตัวอย่างของพฤติกรรมที่กำหนดการใช้งานคือการแพร่กระจายของบิตลำดับสูงเมื่อจำนวนเต็มที่ลงนามถูกเลื่อนไปทางขวา
3.4.3 1 พฤติกรรมพฤติกรรมที่ไม่ได้กำหนดเมื่อใช้โครงสร้างโปรแกรมที่ไม่สามารถทำได้หรือผิดพลาดหรือข้อมูลผิดพลาดซึ่งมาตรฐานสากลนี้ไม่มีข้อกำหนด
2 หมายเหตุพฤติกรรมที่ไม่ได้กำหนดมีความเป็นไปได้มีตั้งแต่การเพิกเฉยต่อสถานการณ์อย่างสมบูรณ์พร้อมผลลัพธ์ที่ไม่สามารถคาดการณ์ได้จนถึงพฤติกรรมในระหว่างการแปลหรือการทำงานของโปรแกรมในลักษณะที่เป็นเอกสารของสภาพแวดล้อม (ไม่ว่าจะมีหรือไม่มี การออกข้อความวินิจฉัย)
3 ตัวอย่างตัวอย่างของพฤติกรรมที่ไม่ได้กำหนดคือพฤติกรรมของจำนวนเต็มล้น
3.4.4การใช้พฤติกรรมที่ไม่ระบุ 1 ค่าที่ไม่ระบุหรือพฤติกรรมอื่น ๆ ที่มาตรฐานสากลนี้ให้ความเป็นไปได้สองทางหรือมากกว่าและไม่มีข้อกำหนดเพิ่มเติมใด ๆ ซึ่งถูกเลือกในกรณี
2 ตัวอย่างตัวอย่างของพฤติกรรมที่ไม่ระบุเป็นลำดับที่ข้อโต้แย้งของฟังก์ชันจะถูกประเมิน
int foo(int x) { if (x >= 0) launch_missiles(); return x << 1; }
คอมไพเลอร์สามารถกำหนดได้ว่าเนื่องจากการเรียกใช้ฟังก์ชันที่ไม่เปิดใช้ขีปนาวุธจะเรียกใช้พฤติกรรมที่ไม่ได้กำหนดซึ่งสามารถเรียกใช้งานได้launch_missiles()
โดยไม่มีเงื่อนไข
การใช้ถ้อยคำง่าย ๆ อาจเข้าใจได้ง่ายกว่านิยามที่เข้มงวดของมาตรฐาน
พฤติกรรมการใช้งานที่กำหนดไว้
ภาษาบอกว่าเรามีประเภทข้อมูล ผู้จำหน่ายคอมไพเลอร์ระบุขนาดที่พวกเขาจะใช้และจัดทำเอกสารสิ่งที่พวกเขาทำ
พฤติกรรมที่ไม่ได้กำหนด
คุณกำลังทำบางสิ่งผิดปกติ ตัวอย่างเช่นคุณมีค่ามากในที่ไม่พอดีint
char
คุณจะใส่ค่าที่ได้char
อย่างไร จริงๆแล้วไม่มีทาง! อะไรจะเกิดขึ้น แต่สิ่งที่เหมาะสมที่สุดจะนำไบต์แรกของ int char
ที่และใส่ไว้ใน มันผิดที่จะทำเช่นนั้นเพื่อกำหนดไบต์แรก แต่นั่นคือสิ่งที่เกิดขึ้นภายใต้ประทุน
ไม่ได้ระบุพฤติกรรม
ฟังก์ชั่นของทั้งสองนี้จะถูกดำเนินการครั้งแรก?
void fun(int n, int m);
int fun1()
{
cout << "fun1";
return 1;
}
int fun2()
{
cout << "fun2";
return 2;
}
...
fun(fun1(), fun2()); // which one is executed first?
ภาษาไม่ได้ระบุการประเมินผลจากซ้ายไปขวาหรือขวาไปซ้าย! ดังนั้นพฤติกรรมที่ไม่ได้ระบุอาจหรืออาจไม่ส่งผลให้เกิดพฤติกรรมที่ไม่ได้กำหนด แต่แน่นอนว่าโปรแกรมของคุณไม่ควรสร้างพฤติกรรมที่ไม่ระบุ
@eSKay ฉันคิดว่าคำถามของคุณควรแก้ไขคำตอบเพื่อชี้แจงเพิ่มเติม :)
สำหรับ
fun(fun1(), fun2());
พฤติกรรม "การใช้งานที่กำหนดไว้" ไม่ใช่หรือ คอมไพเลอร์ต้องเลือกอย่างใดอย่างหนึ่งหรือหลักสูตรอื่นหลังจากทั้งหมด?
ความแตกต่างระหว่างการใช้งานที่กำหนดและไม่ได้ระบุคือคอมไพเลอร์ควรเลือกพฤติกรรมในกรณีแรก แต่ไม่จำเป็นต้องใช้ในกรณีที่สอง sizeof(int)
ยกตัวอย่างเช่นการดำเนินการจะต้องมีเพียงหนึ่งเดียวและความหมายของ ดังนั้นจึงไม่สามารถบอกได้ว่าsizeof(int)
เป็น 4 สำหรับโปรแกรมบางส่วนและ 8 สำหรับโปรแกรมอื่น ซึ่งแตกต่างจากพฤติกรรมที่ไม่ระบุที่คอมไพเลอร์สามารถพูดว่าตกลงฉันจะประเมินข้อโต้แย้งเหล่านี้จากซ้ายไปขวาและข้อโต้แย้งของฟังก์ชั่นต่อไปจะได้รับการประเมินจากขวาไปซ้าย มันสามารถเกิดขึ้นในโปรแกรมเดียวกันที่ว่าทำไมมันจะเรียกว่ายังไม่ระบุ ในความเป็นจริง C ++ สามารถทำได้ง่ายขึ้นหากมีการระบุพฤติกรรมที่ไม่ระบุบางอย่าง ลองดูที่คำตอบของ Dr. Stroustrupที่นี่:
มันถูกอ้างว่าความแตกต่างระหว่างสิ่งที่สามารถผลิตให้กับผู้แปลอิสระนี้และต้องการ "การประเมินจากซ้ายไปขวา" จะต้องมีความสำคัญ ฉันไม่มั่นใจ แต่ด้วยคอมไพเลอร์นับไม่ถ้วน "ออกไปข้างนอก" การใช้ประโยชน์จากอิสรภาพและบางคนก็ปกป้องปกป้องเสรีภาพอย่างกระตือรือร้นการเปลี่ยนแปลงจะเป็นเรื่องยาก ฉันผิดหวังที่คอมไพเลอร์บางคนไม่เตือนรหัสเช่น ++ ฉัน + ฉัน ++ ในทำนองเดียวกันลำดับของการประเมินผลของการขัดแย้งไม่ได้ระบุไว้
IMO มี "สิ่ง" มากเกินไปที่ยังไม่ได้กำหนด, ไม่ระบุ, กำหนดใช้งาน ฯลฯ อย่างไรก็ตามนั่นเป็นเรื่องง่ายที่จะพูดและแม้แต่ให้ตัวอย่าง แต่ยากที่จะแก้ไข ควรสังเกตว่าไม่ใช่เรื่องยากที่จะหลีกเลี่ยงปัญหาส่วนใหญ่และสร้างรหัสพกพา
fun(fun1(), fun2());
พฤติกรรมที่"implementation defined"
ไม่? คอมไพเลอร์ต้องเลือกอย่างใดอย่างหนึ่งหรือหลักสูตรอื่น ๆ หลังจากทั้งหมด?
"I am gonna evaluate these arguments left-to-right and the next function's arguments are evaluated right-to-left"
ฉันเข้าใจสิ่งนี้can
เกิดขึ้น จริง ๆ แล้วมันมีคอมไพเลอร์ที่เราใช้วันนี้หรือไม่?
จากเอกสารเหตุผล C อย่างเป็นทางการ
คำที่ไม่ระบุพฤติกรรมพฤติกรรมที่ไม่ได้กำหนดและพฤติกรรมที่กำหนดไว้ในการใช้งานจะใช้เพื่อจัดหมวดหมู่ผลลัพธ์ของการเขียนโปรแกรมที่คุณสมบัติมาตรฐานไม่ได้หรือไม่สามารถอธิบายได้อย่างสมบูรณ์ เป้าหมายของการใช้การจัดหมวดหมู่นี้คือการอนุญาตให้มีการใช้งานที่หลากหลายซึ่งอนุญาตให้คุณภาพการใช้งานเป็นกำลังที่ใช้งานอยู่ในตลาดรวมทั้งอนุญาตให้ส่วนขยายที่ได้รับความนิยมบางอย่างโดยไม่ต้องลบ cachet ภาคผนวก F ถึงมาตรฐานแคตตาล็อกพฤติกรรมเหล่านั้นซึ่งตกอยู่ในหนึ่งในสามหมวดหมู่นี้
พฤติกรรมที่ไม่ได้ระบุจะทำให้ผู้ติดตั้งใช้งานละติจูดในการแปลโปรแกรม ละติจูดนี้ไม่ขยายจนล้มเหลวในการแปลโปรแกรม
พฤติกรรมที่ไม่ได้กำหนดจะให้สิทธิ์การใช้งานแก่ผู้ใช้เพื่อไม่ให้เกิดข้อผิดพลาดของโปรแกรมที่ยากต่อการวินิจฉัย นอกจากนี้ยังระบุถึงพื้นที่ที่อาจเป็นไปได้สำหรับการขยายภาษา: ผู้ดำเนินการอาจเพิ่มภาษาโดยการให้คำจำกัดความของพฤติกรรมที่ไม่ได้กำหนดอย่างเป็นทางการ
พฤติกรรมที่กำหนดไว้ในการนำไปใช้จะให้อิสระแก่ผู้ดำเนินการในการเลือกวิธีการที่เหมาะสม แต่ต้องการให้ผู้ใช้อธิบายตัวเลือกนี้ พฤติกรรมที่กำหนดให้เป็นไปตามที่กำหนดไว้โดยทั่วไปแล้วเป็นพฤติกรรมที่ผู้ใช้สามารถตัดสินใจในการเขียนโค้ดที่มีความหมายตามคำจำกัดความการนำไปปฏิบัติ ผู้ดำเนินการควรคำนึงถึงเกณฑ์นี้เมื่อตัดสินใจว่าคำจำกัดความการนำไปปฏิบัติที่ครอบคลุมควรเป็นอย่างไร เช่นเดียวกับพฤติกรรมที่ไม่ได้ระบุเพียงแค่การล้มเหลวในการแปลแหล่งข้อมูลที่มีพฤติกรรมที่กำหนดโดยการนำไปปฏิบัตินั้นไม่ได้เป็นการตอบสนองที่เพียงพอ
พฤติกรรมที่ไม่ได้กำหนดกับพฤติกรรมที่ไม่ระบุมีคำอธิบายสั้น ๆ
สรุปสุดท้ายของพวกเขา:
โดยสรุปแล้วพฤติกรรมที่ไม่ได้ระบุมักเป็นสิ่งที่คุณไม่ควรกังวลนอกจากว่าซอฟต์แวร์ของคุณต้องพกพาได้ ในทางกลับกันพฤติกรรมที่ไม่ได้กำหนดไม่เป็นที่พึงปรารถนาเสมอและไม่ควรเกิดขึ้น
ในอดีตทั้งพฤติกรรมการใช้งานที่กำหนดและพฤติกรรมที่ไม่ได้กำหนดเป็นตัวแทนของสถานการณ์ที่ผู้เขียนมาตรฐานคาดหวังว่าคนที่เขียนการใช้งานที่มีคุณภาพจะใช้วิจารณญาณในการตัดสินใจว่าพฤติกรรมรับประกันใด (ถ้ามี) จะเป็นประโยชน์สำหรับโปรแกรมต่างๆ เป้าหมายที่ตั้งใจไว้ ความต้องการของรหัสการบีบอัดตัวเลขระดับสูงค่อนข้างแตกต่างจากรหัสระบบระดับต่ำและทั้ง UB และ IDB ให้ความยืดหยุ่นในการเขียนคอมไพเลอร์เพื่อตอบสนองความต้องการที่แตกต่างกันเหล่านั้น หมวดหมู่เอกสารที่การใช้งานไม่ได้มีประโยชน์สำหรับวัตถุประสงค์เฉพาะใด ๆ หรือแม้กระทั่งเพื่อวัตถุประสงค์ใด ๆ ก็ตาม การใช้งานคุณภาพที่อ้างว่าเหมาะสมสำหรับวัตถุประสงค์เฉพาะอย่างไรก็ตามควรประพฤติตนในลักษณะที่เหมาะสมกับวัตถุประสงค์ดังกล่าวไม่ว่าจะเป็นมาตรฐานต้องใช้มันหรือไม่
ความแตกต่างเพียงอย่างเดียวระหว่างพฤติกรรมการใช้งานที่กำหนดไว้และพฤติกรรมที่ไม่ได้กำหนดไว้คือพฤติกรรมก่อนหน้านั้นต้องการให้การใช้งานกำหนดและจัดทำเอกสารพฤติกรรมที่สอดคล้องกันแม้ในกรณีที่ไม่มีการใช้งานใดๆ เส้นแบ่งระหว่างพวกเขาไม่ใช่ว่าโดยทั่วไปจะมีประโยชน์สำหรับการนำไปใช้เพื่อกำหนดพฤติกรรม (ผู้เขียนคอมไพเลอร์ควรกำหนดพฤติกรรมที่มีประโยชน์เมื่อปฏิบัติว่ามาตรฐานต้องการหรือไม่) แต่อาจมีการใช้งานที่กำหนดพฤติกรรมจะมีราคาแพงพร้อมกัน และไร้ประโยชน์ การตัดสินว่าการใช้งานดังกล่าวอาจมีอยู่ไม่ได้ในทางใดทางหนึ่งรูปร่างหรือรูปแบบแสดงถึงการตัดสินใด ๆ เกี่ยวกับประโยชน์ของการสนับสนุนพฤติกรรมที่กำหนดไว้บนแพลตฟอร์มอื่น ๆ
น่าเสียดายเนื่องจากผู้เขียนคอมไพเลอร์กลางปี 1990 ได้เริ่มตีความการขาดเอกสารเกี่ยวกับพฤติกรรมเป็นการตัดสินว่าการรับรองพฤติกรรมไม่คุ้มค่ากับค่าใช้จ่ายแม้แต่ในแอปพลิเคชั่นที่มีความสำคัญและแม้แต่ในระบบที่ไม่มีค่าใช้จ่ายจริง แทนที่จะรักษา UB เป็นคำเชิญไปใช้วิจารณญาณที่เหมาะสมนักเขียนคอมไพเลอร์ได้เริ่มต้นการรักษามันเป็นข้ออ้างในการไม่ให้ทำเช่นนั้น
ตัวอย่างเช่นให้รหัสต่อไปนี้:
int scaled_velocity(int v, unsigned char pow)
{
if (v > 250)
v = 250;
if (v < -250)
v = -250;
return v << pow;
}
การใช้งานที่สมบูรณ์แบบของสองคนนั้นไม่จำเป็นต้องใช้ความพยายามใด ๆ ในการรักษานิพจน์v << pow
เป็นการเปลี่ยนแปลงแบบสององค์ประกอบโดยไม่คำนึงว่าจะv
เป็นบวกหรือลบ
ปรัชญาที่ต้องการในหมู่นักเขียนบางส่วนของคอมไพเลอร์ของวันนี้ แต่ขอแนะนำว่าเพราะสามารถเป็นเชิงลบหากโปรแกรมจะไปมีส่วนร่วมในพฤติกรรมที่ไม่ได้กำหนดมีเหตุผลที่จะมีโปรแกรมคลิปช่วงเชิงลบของv
v
ถึงแม้ว่าการเปลี่ยนค่าลบเชิงลบที่เคยได้รับการสนับสนุนในคอมไพเลอร์ที่มีนัยสำคัญทุกครั้งและจำนวนมากของรหัสที่มีอยู่อาศัยขึ้นอยู่กับพฤติกรรมที่ปรัชญาสมัยใหม่จะตีความความจริงที่ว่ามาตรฐานบอกว่า หมายความว่าผู้เขียนคอมไพเลอร์ควรเพิกเฉยได้
<<
UB นั้นคือจำนวนลบเป็นกับดักเล็ก ๆ ที่น่ารังเกียจและฉันดีใจที่ได้รับการเตือนว่า!
i+j>k
อัตราผลตอบแทน 1 หรือ 0 ในกรณีที่นอกจากล้นที่มีให้มันมีผลข้างเคียงอื่น ๆ , (int)((unsigned)i+j) > k
คอมไพเลอร์อาจจะไม่สามารถที่จะทำให้การเพิ่มประสิทธิภาพขนาดใหญ่บางอย่างที่จะไม่เป็นไปได้ถ้าโปรแกรมเมอร์เขียนโค้ดเป็น
C ++ มาตรฐาน n3337 § 1.3.10 พฤติกรรมที่กำหนดโดยการนำไปปฏิบัติ
พฤติกรรมสำหรับโปรแกรมที่มีรูปแบบที่ดีและสร้างข้อมูลที่ถูกต้องนั้นขึ้นอยู่กับการนำไปใช้และเอกสารการดำเนินงานแต่ละอย่าง
บางครั้งมาตรฐาน C ++ ไม่ได้กำหนดพฤติกรรมที่เฉพาะเจาะจงในการสร้างบางอย่าง แต่บอกว่าแทนที่จะเลือกเฉพาะพฤติกรรมที่กำหนดไว้อย่างดีจะต้องเลือกและอธิบายโดยการใช้งานเฉพาะ (รุ่นของห้องสมุด) ดังนั้นผู้ใช้ยังสามารถทราบได้อย่างแม่นยำว่าโปรแกรมจะทำงานอย่างไรแม้ว่า Standard จะไม่อธิบายสิ่งนี้
C ++ มาตรฐาน n3337 § 1.3.24 พฤติกรรมที่ไม่ได้กำหนด
พฤติกรรมที่มาตรฐานสากลนี้ไม่มีข้อกำหนด [หมายเหตุ: พฤติกรรมที่ไม่ได้กำหนดอาจเกิดขึ้นเมื่อมาตรฐานสากลนี้ละเว้นการกำหนดพฤติกรรมที่ชัดเจนหรือเมื่อโปรแกรมใช้โครงสร้างที่ผิดพลาดหรือข้อมูลที่ผิดพลาด พฤติกรรมที่ไม่ได้กำหนดอนุญาตช่วงจากการละเว้นสถานการณ์อย่างสมบูรณ์กับผลลัพธ์ที่ไม่สามารถคาดการณ์ได้ถึงพฤติกรรมในระหว่างการแปลหรือการดำเนินการโปรแกรมในลักษณะเอกสารของสภาพแวดล้อม (มีหรือไม่มีการออกข้อความวินิจฉัย) เพื่อยกเลิกการแปลหรือการดำเนินการ ของข้อความวินิจฉัย) การสร้างโปรแกรมที่ผิดพลาดจำนวนมากไม่ก่อให้เกิดพฤติกรรมที่ไม่ได้กำหนด พวกเขาจะต้องได้รับการวินิจฉัย - บันทึกท้าย]
เมื่อโปรแกรมพบโครงสร้างที่ไม่ได้กำหนดตามมาตรฐาน C ++ อนุญาตให้ทำสิ่งที่ต้องการ (อาจส่งอีเมลถึงฉันหรืออาจส่งอีเมลถึงคุณหรืออาจเพิกเฉยต่อรหัสทั้งหมด)
c ++ มาตรฐาน n3337 § 1.3.25 พฤติกรรมที่ไม่ระบุ
พฤติกรรมสำหรับการสร้างโปรแกรมที่มีรูปแบบที่ดีและข้อมูลที่ถูกต้องนั้นขึ้นอยู่กับการใช้งาน [หมายเหตุ: การใช้งานไม่จำเป็นต้องใช้กับเอกสารที่พฤติกรรมเกิดขึ้น ช่วงของพฤติกรรมที่เป็นไปได้มักจะอธิบายโดยมาตรฐานสากลนี้ - บันทึกท้าย]
C ++ Standard ไม่ได้กำหนดพฤติกรรมที่เฉพาะเจาะจงในโครงสร้างบางอย่าง แต่บอกว่าต้องเลือกพฤติกรรมที่กำหนดไว้อย่างดีโดยเฉพาะ ( ไม่จำเป็นต้องอธิบายบอท ) โดยการใช้งานเฉพาะ ดังนั้นในกรณีที่ไม่มีคำอธิบายใด ๆ ผู้ใช้อาจทราบได้ยากว่าโปรแกรมจะทำงานอย่างไร
การดำเนินการที่กำหนดไว้ -
ผู้ปฏิบัติงานต้องการให้มีการบันทึกไว้อย่างดีมาตรฐานให้ทางเลือก แต่ต้องแน่ใจว่าได้รวบรวม
ไม่ได้ระบุ -
เหมือนกับการใช้งานที่กำหนด แต่ไม่ได้ทำเป็นเอกสาร
ไม่ได้กำหนด-
อาจมีอะไรเกิดขึ้นดูแลมัน
uint32_t s;
การประเมิน1u<<s
เมื่อs
33 อาจคาดหวังว่าจะได้รับผลตอบแทน 0 หรืออาจจะเป็นผลตอบแทน 2 แต่ไม่ได้ทำอะไรแปลกประหลาดอื่น คอมไพเลอร์ที่ใหม่กว่าอย่างไรก็ตามการประเมิน1u<<s
อาจทำให้คอมไพเลอร์ตรวจสอบว่าเนื่องจากs
ต้องมีน้อยกว่า 32 ก่อนรหัสใด ๆ ก่อนหรือหลังการแสดงออกซึ่งจะเกี่ยวข้องเฉพาะถ้าs
มี 32 หรือมากกว่าอาจถูกละเว้น