내 코드는 다음과 같습니다.
#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
가지고 일을 내부 구조로 하위 배열.
(Bonus 질문,이 특정 최적화를 해제하는 gcc 플래그가 있습니까?)
2 2
은 다양한 옵션으로 보고합니다 .
s.b
에 한정되는 b[0]
것이 8 개 문자, 따라서 두 가지로 제한된다 : (1) UB 8 비 - 널 문자있다 아웃 오브 바운드 경우 접속, (2)는 널 문자하는, 거기 len은 8보다 작으므로 8로 나누면 0이됩니다. 그래서 두 경우 모두에 동일한 결과를 제공하기 위해 UB를 사용할 수 있습니다 함께 (1) + (2) 컴파일러를 넣어