นี่คือรหัสของฉัน:
#include <string.h>
#include <stdio.h>
typedef char BUF[8];
typedef struct
{
BUF b[23];
} S;
S s;
int main()
{
int n;
memcpy(&s, "1234567812345678", 17);
n = strlen((char *)&s.b) / sizeof(BUF);
printf("%d\n", n);
n = strlen((char *)&s) / sizeof(BUF);
printf("%d\n", n);
}
ใช้ GCC 8.3.0 หรือ 8.2.1 ที่มีระดับการเพิ่มประสิทธิภาพใด ๆ ยกเว้น-O0
ผลผลิตนี้เมื่อผมคาดหวังว่า0 2
2 2
คอมไพเลอร์ตัดสินใจว่าสิ่งstrlen
นั้นถูก จำกัด ขอบเขตb[0]
และดังนั้นจึงไม่สามารถเท่ากับหรือมากกว่าค่าที่ถูกหารด้วย
นี่เป็นข้อบกพร่องในรหัสของฉันหรือเป็นข้อผิดพลาดในคอมไพเลอร์หรือไม่?
สิ่งนี้ไม่ได้สะกดออกมาในมาตรฐานอย่างชัดเจน แต่ฉันคิดว่าการตีความกระแสหลักของตัวชี้ที่มานั้นสำหรับวัตถุใด ๆX
รหัส(char *)&X
ควรสร้างตัวชี้ที่สามารถวนซ้ำไปมาได้ทั้งหมดX
- แนวคิดนี้ควรรักษาไว้แม้ว่าจะX
เกิดขึ้น sub-arrays เป็นโครงสร้างภายใน
(คำถามโบนัสมีการตั้งค่าสถานะ gcc เพื่อปิดการเพิ่มประสิทธิภาพเฉพาะนี้หรือไม่)
2 2
ภายใต้ตัวเลือกต่าง ๆ
s.b
ถูก จำกัด ไว้ที่b[0]
มันถูก จำกัด ไว้ที่ 8 ตัวอักษรและด้วยเหตุนี้สองตัวเลือก: (1) การเข้าถึงนอกขอบเขตในกรณีที่มี 8 ตัวอักษรที่ไม่ใช่โมฆะซึ่งเป็น UB, (2) มีตัวละครที่เป็นโมฆะ len น้อยกว่า 8 ดังนั้นการหารด้วย 8 จะให้ศูนย์ ดังนั้นการรวบรวมคอมไพเลอร์ (1) + (2) สามารถใช้ UB เพื่อให้ผลลัพธ์เดียวกันกับทั้งสองกรณี