다음 코드는 int64_t
을 정의하는 플랫폼에 대한 표준을 합당하게 읽은 상태에서 100 % 정의 된 동작을 가져야하며 long long
이 별칭으로 인식되는지 여부에 관계없이 long long
의 크기와 표현이 같은 경우 호환.gcc 6.2의 저장소 재사용 (앨리어스) 버그입니까?
test3
에 대한
수정 코드 (GCC 6.2 - 64이 -std=c99 -x c -O2
사용) https://godbolt.org/g/75oLGx에서
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
typedef long long T1;
typedef int64_t T2;
#define T1FMT "%lld"
#define T1VALUE 1
#define T2VALUE 2
T1 blah3(void *p1, void *p2)
{
T1 *t1p, *t1p2;
T2 *t2p;
T1 temp;
t1p = p1;
t2p = p2;
*t1p = T1VALUE; // Write as T1
*t2p = T2VALUE; // Write as T2
temp = *t2p; // Read as T2
t1p2 = (T1*)t2p; // Visible T2 to T1 pointer conversion
*t1p2 = temp; // Write as T1
return *t1p; // Read as T1
}
T1 test3(void)
{
void *p = malloc(sizeof (T1) + sizeof (T2));
T1 result = blah3(p,p);
free(p);
return result;
}
int main(void)
{
T1 result = test3();
printf("The result is " T1FMT "\n", result);
return 0;
}
참조 코드 :
- 가치와
long long
기록 1. - 값이 2 인
int64_t
을 작성하여 저장 장치의 유효 유형을int64_t
으로 설정합니다. ,
- 는 (여기서 2이어야 함), 상기 값은 A
long long
저장하여long long
2 개 - 세트 스토리지의 유효 형을 수득한다
int64_t
같은 스토리지 (유효 타입) 읽는다. - 2.
godbolt 사이트에서 GCC 6.2 - 64을 수득한다 형 long long
로 저장을 읽을 수 있지만, 2 산출하지 않는다; 대신에 그것은 1을 산출합니다. gcc가 어떤 유형의 조합을 찾지 못했습니다 이렇게. gcc가 t1p2에 대한 저장소가 효과가 없기 때문에 생략 될 수 있다고 결정하지만 저장소에 유효 유형을 int64_t
에서 long long
으로 변경하는 효과가 있음을 인식하지 못했습니다. 내가없는 결정이 별칭 호환되는 것으로 int64_t
및 long long
을 인식 의심 고려하면서
, 나는 그것이 이전에 보유하고 있던 한 후 값 2를 개최 스토리지의 재사용을 인식하는 GCC의 실패를 정당화 표준에서 아무것도 볼 값 1. 아무 것도 쓰여진 타입이 아닌 다른 타입으로 읽혀지는 것은 없지만, gcc는 "ㅋ"로 전달 된 두 포인터가 별칭이 될 수 없다고 판단하고 있다고 생각합니다.
나는 아무것도 없거나 철저한 버그입니까?
내가 알 수있는 한 버그의 주요 조건은 컴파일러가 스토어를 '* t1p2' (으)로 간주해야한다는 것입니다. gcc의 모든 설치가'int64_t'에 대해 동일한 정의를 사용하는지 여부는 알지 못합니다. 왜냐하면 그 유형이'long long'으로 지정된 플랫폼에서 여기에 표시된 코드는 여기에 표시된 것처럼 잘 작동하지만 T1이 'long'으로 변경되었습니다.만약 표준 컴파일러가 동일한 크기와 표현을 가진 타입 사이의 앨리어싱을 인식하지 못한다고 생각한다면, 그것을 인식하지 못하면 매우 어렵게 될 것입니다 ... – supercat
... 정의 된 데이터 교환 동일한 데이터 형식에 대해 서로 다른 명명 된 형식을 사용하는 API 사이의 유행? 어떤 경우에는, gcc가 그 타입 때문에'T2'가'* t1p'에 영향을 줄 수 없기 때문에 gcc가 쓰기를 결정하고,'T1'으로 쓰는 것은 영향을 끼칠 수 없다고 생각합니다. "이미 쓴"(이전의 쓰기가 무시 된 경우에도). – supercat
@supercat은 그럴듯 해 보입니다. 옵티마이 저 코드로 들어가면 확인할 수 있습니다. –