처음에는 std::numeric_limits<size_t>::max()
라고 생각할 수도 있지만, 거대한 대상이 있다면 여전히 한 끝의 포인터를 제공 할 수 있습니까? 나는 그렇지 않다. 그것은 sizeof(T)
이 산출 할 수있는 가장 큰 값이 std::numeric_limits<size_t>::max()-1
이라는 것을 의미합니까? 내가 맞습니까, 아니면 제가 빠진 것이 있습니까? 이 테스트가 있었다면sizeof (T)의 최대 값은 얼마입니까?
답변
Q : sizeof (T)의 최대 값은 얼마입니까?
A는 : 그것은 맞지 않을 것이기 때문에 std::numeric_limits<size_t>::max()
분명히, sizeof 연산자는 std::numeric_limits<size_t>::max()
보다 큰 값을 반환 할 수 없습니다. 유일한 질문은 ...::max()
을 반환 할 수 있습니까?
예. 다음은 예제별로 증명하는 C++ 03 표준의 제약을 위반하는 유효한 프로그램입니다. 특히,이 프로그램에 §5.3.3 [expr.sizeof] 나열된 모든 제약 조건을 위반하지 않으며에서 §8.3.4 [dcl.array] :
#include <limits>
#include <iostream>
int main() {
typedef char T[std::numeric_limits<size_t>::max()];
std::cout << sizeof(T)<<"\n";
}
실제로 질문을 전체적으로 읽었습니까? Fred는 왜 그것이 틀릴 수도 있다고 생각하는지에 대해 논의합니다. 질문 후 10 분이 넘으면 어떻게 올 수 있고 논쟁하지 않고도 의심을 모순되는 대답을 할 수 있습니까? – sbi
+1, 하나의 과거의 포인터가 갖는 가치는 여전히 문제이지만. – Dabbler
흠, 내 컴퓨터에'4294967295'를 출력 했으므로 틀렸어. – fredoverflow
, 나는 sizeof()
표현 유형 size_t
의 값을 산출 (size_t) -1
그것은'std :: numeric_limits
말할 것입니다. C99 표준에서 6.5.3.4 :
결과의 값은 구현 정의되며, 그 종류 (AN 부호 정수형) stddef.h와 ( 및 기타 헤더)에서 정의를 size_t이다.
따라서 sizeof()가 낼 수있는 최대 값은 SIZE_MAX입니다.
이것은'size_t'에 저장 될 수있는 최대 값입니다. 'sizeof'가'size_t'의 모든 값을 사용한다는 것을 의미하지는 않습니다. –
정확히 잘 정의 된 아니다. 하지만 표준의 안전한 범위 내에서 유지하기 위해, 최대 객체 크기가 두 포인터를 뺄 때, 당신이 얻을 수 있기 때문이다 std::numeric_limits<ptrdiff_t>::max()
있는 ptrdiff_t
하는 부호있는 정수 유형
환호 & HTH입니다.,
슬프게도'std :: numeric_limits
@ avakar : 저주받을거야! 좋은 발견. '다른 산술 오버플로와 마찬가지로 결과가 제공된 공간에 맞지 않으면 그 동작은 정의되지 않습니다. ' – fredoverflow
std::numeric_limits<ptrdiff_t>::max() > std::numeric_limits<size_t>::max()
인 경우 크기가 std::numeric_limits<size_t>::max()
인 개체의 크기를 한 끝의 끝 포인터에서 포인터로 빼서 계산할 수 있습니다.
sizeof(T*) > sizeof(size_t)
인 경우 해당 객체 내부의 각 단일 바이트를 주소 지정하는 데 충분한 별개의 포인터를 가질 수 있습니다 (예 : char 배열의 경우).
sizeof
이 std::numeric_limits<size_t>::max()
을 반환 할 수있는 위치에 포인터를 가져올 수있는 구현을 작성할 수 있습니다.
구현이 세그먼트 화 된 주소를 가진 플랫폼을 대상으로한다면 sizeof (size *)> sizeof 진실 해. –
"나는'sizeof'가'std :: numeric_limits
포인터 연산이 오버플로되는 개체 크기를 허용하는 표준 호환 컴파일러를 사용할 수 있습니다. 그러나 결과는 정의되지 않습니다. C++ 표준에서, 5.7 [expr.] 추가
동일한 배열 객체의 요소에 두 개의 포인터가 감산, 결과 두 배열 요소의 첨자의 차이이다. 결과의 유형은 구현 정의 된 부호가 붙은 정수 유형입니다. 이 유형은
<cstddef>
헤더 (18.2)에std::ptrdiff_t
으로 정의 된 것과 동일한 유형이어야합니다. 산술 오버플로와 마찬가지로 결과가 제공된 공간에 맞지 않으면 동작이 정의되지 않습니다.
배열의 끝을 넘어서서 가리킬 수있는 요구 사항은 size_t
의 범위와는 아무 관계가 없습니다. x
오브젝트가 주어지면 두 포인터를 구분하는 바이트 수를 size_t
으로 표현할 수 없더라도 (&x)+1
이 유효한 포인터 일 가능성이 큽니다.
요구 사항이 일 경우은 최대 포인터 범위의 개체 크기에서 개체 정렬을 뺀 개체 크기의 상한을 의미합니다. 그러나 나는 표준이 그런 유형을 정의 할 수 없다는 것을 어디서나 말할 수 있다고 생각하지 않는다. 하나를 인스턴스화하고 여전히 준수하는 것이 불가능할 것입니다.
한 끝의 포인터를 제공하는 데 필요한 객체 *가 필요합니까? – Dabbler
@Dabbler : C++ 표준에 따르면, 포인터 연산과 관련하여 객체는 크기 1의 배열로 취급 될 수 있기 때문에 원한다면 정확한 문구를 찾을 수 있습니다. – fredoverflow
@Mike : Wrong, 5.7 §1 says'이 연산자의 목적을 위해 비 배열 객체에 대한 포인터는 객체의 유형이 요소 인 길이가 1 인 배열의 첫 번째 요소 인 에 대한 포인터와 동일하게 동작합니다 type.' – fredoverflow