Program Tip

`sizeof`가 * 정말 *`std :: size_t`로 평가됩니까?

programtip 2020. 12. 4. 20:20
반응형

`sizeof`가 * 정말 *`std :: size_t`로 평가됩니까? 할 수 있습니까?


다음 표준 구절을 따르십시오.

[C++11: 5.3.3/6]:sizeof의 결과는 sizeof...유형 상수입니다 std::size_t. [참고 : std::size_t 표준 헤더 <cstddef>(18.2)에 정의되어 있습니다. —end note]

지금:

[C++11: 18.2/6]:형식 size_t은 개체의 크기 (바이트)를 포함 할 수있을만큼 큰 구현 정의 부호없는 정수 형식입니다.

물론,이 구절은로 size_t정의 된 별칭을 요구하지 않지만 typedef표준 헤더 <cstddef>에서 사용할 수 있도록 명시 적으로 명시되어 있기 때문에 포함하지 않으면 사용할 수 <cstddef>있는 모든 보장을 제거해야한다는 것을 읽을 수 있다고 생각 size_t합니다. 프로그램.

그러나 첫 번째 인용문에 따르면 유형의 표현식을 얻을 수 있습니다 std::size_t.

실제로 다음 두 가지 사실을 모두 입증 할 수 있습니다 .

int main()
{
    typedef decltype(sizeof(0)) my_size_t;

    my_size_t x   = 0;  // OK
    std::size_t y = 1;  // error: 'size_t' is not a member of 'std'
}

std::size_t프로그램에 표시되지 않지만 sizeof(0)여전히 하나를 제공합니까? 정말?

그것은 그가 말을하는 것이 정확하지 않은 5.3.3/6되어 결함 , 그리고 실제로 "어떤 동일한 유형이 있는지 std::size_t에 대한 결의를",하지만 하지 std::size_t 자체를?

물론, std::size_t타입 별명 이라면 둘은 하나이고 동일 하지만 실제로 이것이 필요한 곳은 없습니다.


지도를 영토로 혼동하지 마십시오.

유형은 유형 이름으로 이름을 지정할 수 있습니다. 이러한 유형 이름은 내장 될 수 있고, 사용자 정의 유형일 수 있으며, template매개 변수 일 수도 있고 인스턴스화에 따라 여러 다른 유형을 참조 할 수도 있습니다 .

그러나 이름은 유형이 아닙니다. 분명히 표준은 모든 유형에 이름이 있음을 요구하지 않습니다. 클래식 struct {}이름 이없는 유형입니다.

std::size_t유형 이름입니다. sizeof(expression)반환 되는 유형의 이름을 지정 합니다.

컴파일러는 유형에 대한 정식 이름을 가질 수 있습니다. __size_t이것은 고유 한 기본 제공 정식 유형 이름을 갖는 한 가지 방법입니다.

이 절에서 표준 보증은 무엇이든의 유형 sizeof(expression)되고, 당신이 한 번 #include <cstddef>, 이름은 std::size_t이제 그 유형을 말한다.

표준에서는 이름으로 유형을 참조합니다. 그들은 "이 유형 이름이 참조하는 유형"이라고 말하지 않고 단순히 "$ NAME $ 유형"이라고 말합니다. 컴파일러는 원하는 경우 int다른 이름을 결정할 수 __int_32_fast있으며 표준도 반대하지 않습니다.

이 같은 일이 std::nullptr_tstd::initializer_list<Ts>에서도 발생합니다 std::type_info. 이러한 유형의 변수를 사용한다고해서 항상 해당 유형의 이름을 제공하는 헤더가 프로그램에 포함되어야하는 것은 아닙니다.

기존의 C / C ++ 내장 유형에는 모두 헤더가 필요하지 않은 표준 이름이 있습니다. 단점은 전역 범위의 새 유형 이름이 다른 식별자와 충돌하므로 기존 코드가 손상된다는 것입니다.

헤더 파일을 포함하여 이름을 얻을 수있는 "이름없는 유형"을 사용함으로써 이러한 문제를 피할 수 있습니다.


표준 sizeof(expr)은의 유형이 std::size_t. using을 사용 sizeof(expr)하면 이름을 std::size_t사용할 수 있다는 의무는 없으며 std::size_t내장 정수 유형 중 하나의 이름 만 지정하기 때문에 실제로 문제가 없습니다.


내가 이해하는대로이 표준 구절에는 다음 표현이 필요합니다.

typeid(sizeof(0)) == typeid(std::size_t)

항상 양보 true합니다. 당신이 실제 식별자를 사용하는 경우 std::size_t, ::size_t또는 다른 별명을 / 타입 정의가에 따라, 긴 형태의 신원 등으로 관련이없는 것 std::typeinfo::operator==(), 보존됩니다.

동일한 유형의 신원 문제가 언어의 다른 곳에서 나타납니다. 예를 들어 내 64 비트 컴퓨터에서 함수 재정의로 인해 다음 코드가 컴파일되지 않습니다.

#include <cstddef>
void foo(std::size_t x)
{}

void foo(unsigned long x)
{}

예.

에 의해 생성 된 유형은 sizeof부호없는 정수 유형입니다. 구현은 그것이 무엇인지 정의합니다.

예를 들어 특정 구현에서 sizeof표현식 의 유형은 unsigned long.

std::size_t,이면 typedef은 대체 이름 일뿐입니다 unsigned long. 그래서이 두 문장 :

유형은 유형 sizeof ...상수입니다.unsigned long

유형은 유형 sizeof ...상수입니다.std::size_t

are saying exactly the same thing for that implementation. The type unsigned long and the type std::size_t are the same type. The difference is that the latter is accurate for all (conforming) implementations, where std::size_t might be an alias for, say, unsigned int or some other unsigned type.

As far as the compiler is concerned, sizeof yields a result of type unsigned long; the compiler (as opposed to the runtime library) needn't have any knowledge of the name size_t.

This all assumes that std::size_t (or just size_t if you're talking about C) is a typedef. That's not spelled out in either the C or the C++ standard. Nevertheless, an implementation can straightforwardly conform to the requirements of the standard by making size_t a typedef. I don't believe there's any other portable way to satisfy those requirements. (It can't be a macro or an implementation-defined keyword because that would infringe on the user's name space, and a macro wouldn't be scoped within the std namespace.) A compiler could make size_t some implementation-specific construct other than a typedef, but since a typedef works perfectly well, there's no point in doing so. It would be nice, IMHO, if the standard stated that size_t is a typedef.

(An irrelevant aside: The real problem is that the standard refers to the result as a "constant". In ISO C, a "constant" is a token, such as an integer literal. C++, as far as I know, doesn't define the noun "constant", but it does refer to the ISO C definition of the term. sizeof ... is a constant expression; it's not a constant. Calling the result a "constant value" would have been reasonable.)


It is the same type but you have to include that header to use it.

참고URL : https://stackoverflow.com/questions/20808905/does-sizeof-really-evaluate-to-a-stdsize-t-can-it

반응형