Memcpy(&a + 1, &b + 1, 0)가 C11에 정의되어 있습니까?
이 질문은 다음의 정의에 대한 이전 질문에 이어집니다.memcpy(0, 0, 0)
, 정의되지 않은 행동으로 결정된 것입니다.
연결된 질문에서 알 수 있듯이 답은 C11의 조항 7.1.4:1의 내용에 달려 있습니다.
다음의 각 문은 다음의 상세한 설명에 달리 명시적으로 언급되지 않는 한 적용됩니다.함수에 대한 인수의 값(예: 함수의 도메인 외부의 값, 프로그램의 주소 공간 외부의 포인터 또는 널 포인터)이 잘못된 경우 […] 동작은 정의되지 않습니다. […]
표준함수memcpy()
에 대한 포인터를 기대합니다.void
그리고.const void
, 이와 같이:
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
표준에는 "유효한" 포인터라는 두 가지 개념이 있기 때문에 질문할 가치가 있습니다: 포인터 산술을 통해 유효하게 얻을 수 있는 포인터와 유효하게 비교할 수 있는 포인터가 있습니다.<
,>
같은 객체 안에 있는 다른 포인터들로.그리고 재참조에 유효한 포인터들이 있습니다.이전 클래스는 다음과 같은 "1-past" 포인터를 포함합니다.&a + 1
그리고.&b + 1
다음 토막글에서 후자의 클래스는 이것들을 유효한 것으로 포함하지 않습니다.
char a;
const char b = '7';
memcpy(&a + 1, &b + 1, 0);
위의 토막글이 정의된 행동으로 간주되어야 하는가, 의 주장에 비추어 볼 때.memcpy()
에 대한 지침으로 타이핑되어 있습니다.void
어쨌든, 그들 각각의 유효성의 문제는 그들을 재참조하는 것이 될 수 없습니다.아니면 해야합니다.&a + 1
그리고.&b + 1
"프로그램의 주소 공간 outside"로 간주됩니까?
저는 표준 C 기능의 효과를 공식화하는 과정에 있기 때문에 이 문제가 중요합니다.나는 한가지 전제조건을 썼습니다.memcpy()
~하듯이requires \valid(s1+(0 .. n-1));
GCC 4.9가 위 수식에 표현된 것 이상으로 그러한 라이브러리 함수 호출을 공격적으로 최적화하기 시작했다는 것이 알려지기 전까지(실제로).공식을\valid(s1+(0 .. n-1))
이 특별한 사양 언어는 다음과 같습니다.true
언제n
이다.0
, 그리고 GCC 4.9가 최적화하기 위해 의존하는 정의되지 않은 동작을 포착하지 못합니다.
C11은 다음과 같이 말합니다.
(C11, 7.24.2.1p2) "memcpy 함수는 s2가 가리키는 객체에서 s1이 가리키는 객체로 n개의 문자를 복사합니다."
&a + 1
그 자체는 정수 덧셈에 대한 유효한 포인터이지만,&a + 1
는 개체에 대한 포인터가 아니므로 호출은 정의되지 않은 동작을 호출합니다.
표준에 따른 "올바른" 답은 일치하지 않는 것처럼 보이지만, int[6]; int[6]; 모두 뒤에 오는 것이 솔직하지 않다는 것을 알 수 있습니다.
memcpy(a+0, b+0, 6);
memcpy(a+1, b+1, 5);
memcpy(a+2, b+2, 4);
memcpy(a+3, b+3, 3);
memcpy(a+4, b+4, 2);
memcpy(a+5, b+5, 1);
유효해야 합니다(그리고 배열의 끝에 끝나는 영역을 복사).
memcpy(a+6, b+6, 0);
는 카운트에 비추어 유효하지만 주소에는 유효하지 않습니다.복사된 영역의 끝과 같습니다!
개인적으로, memcpy(0,0,0)도 유효하다고 정의하고 싶지만(유효한 포인터만 요구하고 객체는 요구하지 않는 이론적 근거가 있음), 적어도 "배열의 끝"의 경우는 배열의 끝에 있는 영역을 복사하기 위한 일반적인 패턴에 대한 실제 예외인 반면, 단 하나의 경우입니다.
언급URL : https://stackoverflow.com/questions/25390577/is-memcpya-1-b-1-0-defined-in-c11
'IT' 카테고리의 다른 글
Oracle 실행 계획의 액세스 및 필터 술어 (0) | 2023.10.30 |
---|---|
자바스크립트에서 '정의'란 무엇에 쓰이는가? (0) | 2023.10.30 |
C 언어의 새 행 문자는 무엇입니까?\r 또는 \n? (0) | 2023.10.30 |
will IF SIGNAL SQLSTATE in mariadb exit stored procedure? (0) | 2023.10.30 |
약한 연결의 실용적인 응용은 무엇입니까? (0) | 2023.10.30 |