2011-10-31 1 views
8

처음에는 std::numeric_limits<size_t>::max()라고 생각할 수도 있지만, 거대한 대상이 있다면 여전히 한 끝의 포인터를 제공 할 수 있습니까? 나는 그렇지 않다. 그것은 sizeof(T)이 산출 할 수있는 가장 큰 값이 std::numeric_limits<size_t>::max()-1이라는 것을 의미합니까? 내가 맞습니까, 아니면 제가 빠진 것이 있습니까? 이 테스트가 있었다면sizeof (T)의 최대 값은 얼마입니까?

+0

한 끝의 포인터를 제공하는 데 필요한 객체 *가 필요합니까? – Dabbler

+0

@Dabbler : C++ 표준에 따르면, 포인터 연산과 관련하여 객체는 크기 1의 배열로 취급 될 수 있기 때문에 원한다면 정확한 문구를 찾을 수 있습니다. – fredoverflow

+0

@Mike : Wrong, 5.7 §1 says'이 연산자의 목적을 위해 비 배열 객체에 대한 포인터는 객체의 유형이 요소 인 길이가 1 인 배열의 첫 번째 요소 인 에 대한 포인터와 동일하게 동작합니다 type.' – fredoverflow

답변

3

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"; 
} 
+0

실제로 질문을 전체적으로 읽었습니까? Fred는 왜 그것이 틀릴 수도 있다고 생각하는지에 대해 논의합니다. 질문 후 10 분이 넘으면 어떻게 올 수 있고 논쟁하지 않고도 의심을 모순되는 대답을 할 수 있습니까? – sbi

+0

+1, 하나의 과거의 포인터가 갖는 가치는 여전히 문제이지만. – Dabbler

+0

흠, 내 컴퓨터에'4294967295'를 출력 했으므로 틀렸어. – fredoverflow

0

, 나는 sizeof() 표현 유형 size_t의 값을 산출 (size_t) -1

+2

그것은'std :: numeric_limits :: max()'입니다. –

0

말할 것입니다. C99 표준에서 6.5.3.4 :

결과의 값은 구현 정의되며, 그 종류 (AN 부호 정수형) stddef.h와 ( 및 기타 헤더)에서 정의를 size_t이다.

따라서 sizeof()가 낼 수있는 최대 값은 SIZE_MAX입니다.

+2

이것은'size_t'에 저장 될 수있는 최대 값입니다. 'sizeof'가'size_t'의 모든 값을 사용한다는 것을 의미하지는 않습니다. –

2

정확히 잘 정의 된 아니다. 하지만 표준의 안전한 범위 내에서 유지하기 위해, 최대 객체 크기가 두 포인터를 뺄 때, 당신이 얻을 수 있기 때문이다 std::numeric_limits<ptrdiff_t>::max()

있는 ptrdiff_t

하는 부호있는 정수 유형

환호 & HTH입니다.,

+2

슬프게도'std :: numeric_limits :: max()'보다 큰 배열을 가질 수 있습니다. 이 배열에서 너무 멀리 떨어져있는 두 개의 포인터를 빼면 동작은 정의되지 않습니다. [expr.add]/6을 참조하십시오. – avakar

+0

@ avakar : 저주받을거야! 좋은 발견. '다른 산술 오버플로와 마찬가지로 결과가 제공된 공간에 맞지 않으면 그 동작은 정의되지 않습니다. ' – fredoverflow

3

std::numeric_limits<ptrdiff_t>::max() > std::numeric_limits<size_t>::max() 인 경우 크기가 std::numeric_limits<size_t>::max() 인 개체의 크기를 한 끝의 끝 포인터에서 포인터로 빼서 계산할 수 있습니다.

sizeof(T*) > sizeof(size_t) 인 경우 해당 객체 내부의 각 단일 바이트를 주소 지정하는 데 충분한 별개의 포인터를 가질 수 있습니다 (예 : char 배열의 경우).

sizeofstd::numeric_limits<size_t>::max()을 반환 할 수있는 위치에 포인터를 가져올 수있는 구현을 작성할 수 있습니다.

+1

구현이 세그먼트 화 된 주소를 가진 플랫폼을 대상으로한다면 sizeof (size *)> sizeof 진실 해. –

+0

"나는'sizeof'가'std :: numeric_limits :: max()']"를 반환 할 수있는 구현이 있는지 의심 스럽습니다. g ++는 이러한 구현 중 하나입니다. –

0

포인터 연산이 오버플로되는 개체 크기를 허용하는 표준 호환 컴파일러를 사용할 수 있습니다. 그러나 결과는 정의되지 않습니다. C++ 표준에서, 5.7 [expr.] 추가

동일한 배열 객체의 요소에 두 개의 포인터가 감산

, 결과 두 배열 요소의 첨자의 차이이다. 결과의 유형은 구현 정의 된 부호가 붙은 정수 유형입니다. 이 유형은 <cstddef> 헤더 (18.2)에 std::ptrdiff_t으로 정의 된 것과 동일한 유형이어야합니다. 산술 오버플로와 마찬가지로 결과가 제공된 공간에 맞지 않으면 동작이 정의되지 않습니다.

1

배열의 끝을 넘어서서 가리킬 수있는 요구 사항은 size_t의 범위와는 아무 관계가 없습니다. x 오브젝트가 주어지면 두 포인터를 구분하는 바이트 수를 size_t으로 표현할 수 없더라도 (&x)+1이 유효한 포인터 일 가능성이 큽니다.

요구 사항이 일 경우은 최대 포인터 범위의 개체 크기에서 개체 정렬을 뺀 개체 크기의 상한을 의미합니다. 그러나 나는 표준이 그런 유형을 정의 할 수 없다는 것을 어디서나 말할 수 있다고 생각하지 않는다. 하나를 인스턴스화하고 여전히 준수하는 것이 불가능할 것입니다.