프로그래밍 언어 문법 | ||
{{{#!wiki style="margin: -16px -11px; word-break: keep-all" | <colbgcolor=#0095c7><colcolor=#fff,#000> 언어 문법 | C( 포인터 · 구조체 · size_t) · C++( 자료형 · 클래스 · 이름공간 · 상수 표현식 · 특성) · C# · Java · Python( 함수 · 모듈) · Kotlin · MATLAB · SQL · PHP · JavaScript · Haskell( 모나드) |
마크업 문법 | HTML · CSS | |
개념과 용어 | 함수( 인라인 함수 · 고차 함수 · 람다식) · 리터럴 · 상속 · 예외 · 조건문 · 참조에 의한 호출 · eval | |
기타 | == · === · deprecated · NaN · null · undefined · 배커스-나우르 표기법 | |
프로그래밍 언어 예제 · 목록 · 분류 | }}} |
1. 개요
C/C++ 에서 쓰이는 데이터 타입이다. C80/C90 표준에 정의되어 있다.2. 설명
size_t
는 해당 시스템에서 어떤 객체나 값이 포함할 수 있는 최대 크기의 데이터를 표현하는 타입으로 반드시 unsigned 형으로 나타낸다. stddef.h 및 cstddef 헤더에 정의되어 있다.아래는 C99 원문.
size_t
can store the maximum size of a theoretically possible object of any type메모리 관련 표준 라이브러리 함수(malloc, memcpy, memcmp, memset, memchr 등)는 크기에 관해 항상 이 자료형을 쓴다. 운영체제에 따라 메모리 주소의 크기, 처리 가능한 최대 메모리 크기가 달라지니 운영체제에 따라 크기가 가변적인 이 자료형을 쓰는 것이다. 메모리 함수들은 에러 발생시 치명적이므로 다소 불편해도 엄격하게 다루는게 맞다. 아래와 같이 입맛에 맞게 강제 형변환시 조심스럽게 처리해야 할 것이다.
C++에서는 stddef.h 대신 cstddef를 include하면
std::size_t
로도 쓸 수 있으며 명세도 C와 동일하다.========================================
아래는 32비트 프로그래밍 관점에서 unsigned 자료형(부호 없는 양수 자료형)을 불편해하는 일부의 별개적 입장으로 보인다. 요즘처럼 64비트 프로그래밍이 자리잡아가는 시대에는 맞지 않다. 64비트 시스템에서는 size_t는 8바이트를 의미하므로 강제로 4바이트 int로 형변환하는 시도 자체가 잘못된 것이다. 그리고 32비트 프로그래밍에서도 메모리 관련 함수는 모두 unsigend 자료형을 쓴다. c 표준함수(malloc, memcpy 등)에서는 size_t 자료형을 쓰고 Windows API(VitrualAlloc, WriteFile 등)에서는 DWORD 자료형(unsigned long)을 쓴다. 크기를 signed형으로 하는 경우 절반은 음수 영역을 나타내므로 양수 영역은 unsigned형의 절반으로 잘리게 된다. 32비트 시스템에서 최대 메모리 인식 크기인 4GB의 반토막인 2GB 밖에 처리 못하게 된다. 문자열이나 작은 파일은 일반적으로 크기가 2GB 넘을 정도로 거대하지 않아 signed int형으로 강제 형변환해서 처리해도 별 문제 없지만 미디어 파일 같은 큰 파일의 메모리 처리에서는 주의하고 조심해야 한다. 아래는 일부의 편의적인 입장에서 쓴 글이라고 참고 정도만 하자.
=========================================
표준이라는 점과는 별개로 이 자료형의 효용성에 의문을 갖는 프로그래머들이 꽤 많은데, 이유는 다음과 같다.
- unsigned.
- 가장 골치아픈 변수 버그들 중 하나인 unsigned와 signed 변수의 혼합 계산 오류 때문에 쓰기가 꺼려진다. 정말 잘 제어해서 쓰거나 다른 연산이 불필요한 for 루프 카운터에만 쓰는 식이 아니라면 이 문제가 언제 터질지 모른다. 오버플로우나 막장 연산자 혼합문제와 비슷한 양상의 계산 버그가 생길 수 있다.
-
어쩔 수 없이
size_t
를 쓰게 되었는데 signed로의 변환이 필요하다면 캐스팅을 써야 하는데, 이 과정에서 성능 하락이 있을 수 있다. 반대로도 마찬가지다. -
역방향 루프 같은 경우에는 쓰려면 일부러 복잡하게 바꿔야 한다. 그냥 int 같은 걸 쓰면 알고리즘이 좀 달라도 비슷하게 쓸 수 있는 문장을
size_t
를 쓰는 순간 마이너스를 고려해서 두 가지로 써야 한다.
표준 라이브러리은 죄다
size_t
로 고정되어 있기 때문에 어쩔 수 없이 컴파일 경고를 없애기 위해 써야 하는 경우도 꽤 있다.size_t
의 대체품을 찾는다면 쓸 수 있는 가장 좋은 것은 int
, 필요하다면 unsigned int
이며auto
를 써 주면 개발 편의성도 잡고 컴파일 경고까지 쉽게 없애줄 수 있다. auto
가 지원이 안 된다면 static_cast<int>(value)
[1], (int)value
[2]들을 활용하면 강제로 size_t
의 문제점에서 벗어날 수 있다.