Automatic Variable ใน entry ที่แล้วผมยกตัวอย่าง order of evaluation ว่าเป็น undefined behavior ที่น่าจะเป็นปัญหามากที่สุด เพราะเข้าใจยาก หาที่ผิดยาก แล้วก็แก้ไขได้ยากด้วย entry นี้มาดูเรื่องที่ง่ายลงมาหน่อย เป็น undefined เหมือนกัน แต่เป็น undefined value ครับ เรื่องที่จะเล่าคือ ค่าเริ่มต้นของ automatic variable ครับ automatic variable หรือ auto variable คือ variable ที่ไม่ใช่ static หรือ extern ซึ่งถูก declare อยู่ภายใน function ครับ ตัวอย่าง เช่น int function() { int x, y; /* อันนี้เป็น automatic variable */ static int seed; /* อันนี้เป็น static variable */ extern int errno; /* อันนี้เป็น extern variable */ ... return 0; } เมื่อมีการเรียกใช้ function compiler จะ allocate ที่สำหรับ automatic variable โดยให้อยู่ใน memory ส่วนที่เป็น stack พอโปรแกรมทำงานจบและ return ออกจาก function จะมีการคืน memory ใน stack ทำให้ variable พวกนี้หายไป หรือ access ไม่ได้ ด้วยเหตุที่ variable พวกนี้เกิดพร้อมกับการเรียกใช้ function และหายไปหลังจากจบ function จึงถูกเรียกว่า automatic variable หรือ auto variable ครับ บางทีก็เรียก auto variable ว่า local variable เพราะขอบเขตการใช้งานของ variable พวกนี้จะอยู่ภายใต้ block ที่มันสังกัดอยู่ block นั้นจะเริ่มจากเครื่องหมาย { ไปจนถึงเครื่องหมาย } พอออกนอก block ก็จะไม่เห็น variable ที่ declare ใน block แล้วครับ variable พวกนี้เลยมีอีกชื่อหนึ่งว่า local variable คืออยู่ประจำ block นั่นเอง standard C ล่าสุดคือ C99 ครับ ออกมาเมื่อปี 1999 standard ก่อนหน้านี้ กำหนดว่าการ declare auto variable จะทำได้เฉพาะที่ส่วนบนของ block หลังจากเครื่องหมาย { และก่อนที่จะมี statement แรกเท่านั้น แต่ใน standard C99 จะกำหนดให้ declare ที่ไหนใน block ก็ได้ครับ ดู code ตัวอย่าง { /* block เริ่มที่นี่ */ int i; i = 1; /* statement แรก */ int j; /* standard compiler ก่อน C99 จะ error ที่นี่ */ j = 2; ... } /* block จบที่นี่ */ ค่าเริ่มต้นของ auto variable จะเป็น undefined value คือเป็นอะไรก็ได้ เพราะตอน compiler allocate variable ใน stack ค่าของ memory ใน stack เคยเป็นอะไรอยู่ ก็เป็นอยู่แบบนั้น auto variable เลยมีค่าเป็นค่าเดิมของ memory ใน stack คือเป็นอะไรก็ไม่รู้ โดยปรกติการใช้งาน auto variable ต้องตั้งค่าเริ่มต้นก่อน ไม่งั้นค่าที่ มั่วๆ เป็นอะไรก็ไม่รู้ อาจทำให้โปรแกรมทำงานผิดได้ โดยเฉพาะพวก pointer ถ้ามันชี้ไปที่ไหนก็ไม่รู้ แล้วเราดันไปใช้มัน ทำโปรแกรมตายมาเยอะแล้วครับ เรียกได้ว่า เป็นข้อผิดพลาดที่พบได้บ่อยทีเดียว แล้วทำไม standard C ถึงไม่กำหนดให้ compiler ทำการตั้งค่าเริ่มต้นของ auto variable ไปเลย เหตุผลคือ เพื่อประสิทธิภาพ เพื่อความเร็วครับ auto variable ในแต่ละ function จะมีขนาดรวมกันใหญ่แค่ไหนก็ได้ จากไม่กี่ byte จนเป็นแสนเป็นล้าน byte ก็มี ถ้าทุกครั้งที่เรียกใช้ function แล้วต้องตั้งค่าเริ่มต้นให้กับ variable ทั้งหมด โปรแกรมคงทำงานช้าลงไปมาก เลยกำหนดให้คนเขียนโปรแกรมทำเอง compiler ไม่ทำให้ครับ และบางทีคนเขียนโปรแกรมอาจไม่ต้องการตั้งค่าเริ่มต้นให้กับทุก variable คือทำเฉพาะบาง variable หรือต้องการทำเฉพาะบางส่วนของ variable เช่นพวกที่เป็น array, struct หรือ union หรือมีเฉพาะบางเงื่อนไขเท่านั้น ถึงจะทำ เรียกได้ว่าเลือกทำเท่าที่จำเป็นครับ ไม่ได้บังคับ ทีนี้จะทำอย่างไร compiler ไม่ยอมทำให้ แต่ถ้าคนเขียนโปรแกรมลืมทำ โปรแกรมก็ทำงานผิด ก็อย่างที่รู้กันว่า หาที่ผิดในภาษา C มันยากขนาดไหน จริงๆแล้ว compiler ส่วนใหญ่ก็ใหู้ตัวช่วยมาด้วยครับ คือ compiler จะมี option ให้ทำการเตือน ถ้ามีการใช้ auto variable โดยที่ยังไม่ได้ตั้งค่า ไม่ใช่เตือนเฉพาะเรื่องนี้เท่านั้น เตือนได้สารพัดเรื่องแหละครับ ดังนั้นจึงควรใช้ warning option พวกนี้ให้เป็นประโยชน์ ใช้ option สูงสุดได้ยิ่งดี เช่น VisualC 6.0 ก็ใช้ /W4 GNU gcc ก็ใช้ -Wall เวลา compile แล้วมี warning message ก็ควรอ่านให้ละเอียด ทำความเข้าใจว่าเกิดอะไรขึ้น อย่าไปคิดว่าเป็นแค่ warning ไม่เป็นไร แต่อย่าคาดหวังว่า compiler จะ warning ได้ถูกต้องเสมอไปนะครับ บางที compiler ก็ถูกหลอกได้เหมือนกัน |