Storage-class specifiers
객체와 함수의 저장 기간(storage duration) 과 링크(linkage) 를 지정합니다:
-
-
auto- 자동 지속 기간과 링크 없음 -
register- 자동 지속 기간과 링크 없음; 이 변수의 주소를 취할 수 없음 -
static- 정적 지속 기간과 내부 링크 (블록 범위가 아닌 경우) -
extern- 정적 지속 기간과 외부 링크 (이미 내부로 선언되지 않은 경우)
-
|
(C11부터) |
목차 |
설명
저장 클래스 지정자는 선언 및 복합 리터럴 표현식에서 (C23부터) 나타납니다. 최대 하나의 지정자만 사용할 수 있습니다 , 단 _Thread_local (C23 이전) thread_local (C23부터) 는 static 또는 extern 과 결합되어 링크를 조정할 수 있습니다 (C11부터) . 저장 클래스 지정자는 선언하는 이름들의 두 가지 독립적인 속성인 저장 기간 과 링크 을 결정합니다.
_Alignas
(C23 이전)
alignas
(C23 이후)
를 사용할 수 없고
(C11 이후)
,
register
배열은 포인터로 변환할 수 없습니다.
|
5)
_Thread_local
(C23까지)
thread_local
(C23부터)
는
스레드 저장 기간
을 나타냅니다. 함수 선언과 함께 사용할 수 없습니다. 객체 선언에 사용되는 경우, 동일한 객체의 모든 선언에 존재해야 합니다. 블록 범위 선언에 사용되는 경우,
static
또는
extern
과 결합되어 링크age를 결정해야 합니다.
|
(C11부터) |
저장 클래스 지정자가 제공되지 않으면 기본값은 다음과 같습니다:
- extern 모든 함수에 대해
- extern 파일 범위의 객체에 대해
- auto 블록 범위의 객체에 대해
저장 클래스 지정자와 함께 선언된 모든 구조체나 공용체에 대해, 저장 기간(연결은 제외)이 해당 멤버들에 재귀적으로 적용됩니다.
블록 범위의 함수 선언은 extern 을 사용하거나 아무것도 사용하지 않을 수 있습니다. 파일 범위의 함수 선언은 extern 또는 static 을 사용할 수 있습니다.
함수 매개변수는 register 이외의 저장류 지정자를 사용할 수 없습니다. static 이 배열 타입의 함수 매개변수에서 특별한 의미를 가진다는 점에 유의하십시오.
저장 기간
모든 객체 는 저장 기간 이라는 속성을 가지며, 이는 객체의 수명 을 제한합니다. C 언어에는 네 가지 종류의 저장 기간이 있습니다:
-
- automatic 저장 기간. 저장 공간은 객체가 선언된 블록 이 진입될 때 할당되고, 어떤 방식으로든 블록을 빠져나올 때( goto , return , 끝에 도달) 해제됩니다. 한 가지 예외는 VLA 입니다. 이들의 저장 공간은 블록 진입 시가 아닌 선언이 실행될 때 할당되며, 블록을 빠져나올 때가 아닌 선언이 범위를 벗어날 때 해제됩니다 (C99부터) . 블록이 재귀적으로 진입되면, 모든 재귀 수준에 대해 새로운 할당이 수행됩니다. 모든 함수 매개변수와 static 이 아닌 블록 범위 객체는 이 저장 기간을 가지며, 블록 범위에서 사용되는 복합 리터럴 도 마찬가지입니다 (C23까지)
- static 저장 기간. 저장 기간은 프로그램 전체 실행 기간이며, 객체에 저장된 값은 main 함수 이전에 단 한 번만 초기화됩니다. static 으로 선언된 모든 객체와 내부 또는 외부 링크를 가지는 모든 객체 중 _Thread_local (C23까지) thread_local (C23부터) 으로 선언되지 않은 객체 (C11부터) 는 이 저장 기간을 가집니다.
|
(C11 이후) |
-
- allocated 저장 기간. 저장 공간은 동적 메모리 할당 함수를 사용하여 요청 시 할당 및 해제됩니다.
링키지
링키지(Linkage)는 식별자(변수나 함수)가 다른 스코프에서 참조될 수 있는 능력을 의미합니다. 동일한 식별자를 가진 변수나 함수가 여러 스코프에서 선언되었지만, 모든 스코프에서 참조할 수 없는 경우 여러 개의 변수 인스턴스가 생성됩니다. 다음과 같은 링키지 유형이 인식됩니다:
-
-
연결 없음(no linkage)
. 해당 변수나 함수는 자신이 속한 스코프(블록 스코프) 내에서만 참조될 수 있습니다.
extern으로 선언되지 않은 모든 블록 스코프 변수와 모든 함수 매개변수, 그리고 함수나 변수가 아닌 모든 식별자는 이 연결을 가집니다.
-
연결 없음(no linkage)
. 해당 변수나 함수는 자신이 속한 스코프(블록 스코프) 내에서만 참조될 수 있습니다.
-
-
internal linkage
. 변수나 함수는 현재 번역 단위의 모든 스코프에서 참조될 수 있습니다.
static또는constexpr(C23부터) 으로 선언된 모든 파일 스코프 변수는 이 링크를 가지며,static으로 선언된 모든 파일 스코프 함수도 마찬가지입니다(정적 함수 선언은 파일 스코프에서만 허용됩니다).
-
internal linkage
. 변수나 함수는 현재 번역 단위의 모든 스코프에서 참조될 수 있습니다.
-
-
외부 연결(external linkage)
. 해당 변수나 함수는 전체 프로그램의 다른 모든 번역 단위에서 참조될 수 있습니다.
static으로 선언되지 않은 모든 파일 범위 변수 또는constexpr(C23부터) 은 이 연결을 가지며,static으로 선언되지 않은 모든 파일 범위 함수 선언, 모든 블록 범위 함수 선언, 그리고 추가적으로extern으로 선언된 모든 변수나 함수는 해당 지점에서 내부 연결을 가진 이전 선언이 보이지 않는 한 이 연결을 가집니다.
-
외부 연결(external linkage)
. 해당 변수나 함수는 전체 프로그램의 다른 모든 번역 단위에서 참조될 수 있습니다.
동일한 번역 단위에서 동일한 식별자가 내부 링크와 외부 링크를 모두 가지는 경우, 그 동작은 정의되지 않습니다. 이는 잠정적 정의 가 사용될 때 발생할 수 있습니다.
링키지와 라이브러리
|
이 섹션은 불완전합니다
이유: 이것이 Miscellaneous 아래 c/language에 별도의 최상위 항목이 되어야 합니까? |
외부 연결을 가진 선언들은 일반적으로 헤더 파일에서 제공되며, 이 파일을 #include 하는 모든 번역 단위가 다른 곳에서 정의된 동일한 식별자를 참조할 수 있도록 합니다.
헤더 파일에 내부 링크를 가진 선언이 존재하면, 해당 파일을 포함하는 각 번역 단위마다 별개이고 독립적인 객체가 생성됩니다.
라이브러리 인터페이스, 헤더 파일 "flib.h":
#ifndef FLIB_H #define FLIB_H void f(void); // 외부 링크를 가진 함수 선언 extern int state; // 외부 링크를 가진 변수 선언 static const int size = 5; // 내부 링크를 가진 읽기 전용 변수 정의 enum { MAX = 10 }; // 상수 정의 inline int sum (int a, int b) { return a + b; } // 인라인 함수 정의 #endif // FLIB_H
라이브러리 구현, 소스 파일 "flib.c":
#include "flib.h" static void local_f(int s) {} // 내부 링크를 가진 정의 (이 파일에서만 사용됨) static int local_state; // 내부 링크를 가진 정의 (이 파일에서만 사용됨) int state; // 외부 링크를 가진 정의 (main.c에서 사용됨) void f(void) { local_f(state); } // 외부 링크를 가진 정의 (main.c에서 사용됨)
애플리케이션 코드, 소스 파일 "main.c":
#include "flib.h" int main(void) { int x[MAX] = {size}; // 상수와 읽기 전용 변수를 사용 state = 7; // flib.c의 state를 수정 f(); // flib.c의 f() 함수 호출 }
키워드
auto , register , static , extern , _Thread_local thread_local
참고 사항
|
키워드 _Thread_local 은 일반적으로 헤더 파일 <threads.h> 에 정의된 편의 매크로 thread_local 을 통해 사용됩니다. |
(C23 이전) |
typedef
및
constexpr
(C23부터)
지정자는 C 언어 문법에서 형식적으로 저장 클래스 지정자로 분류되지만, 실제 저장 방식을 지정하지는 않습니다.
|
auto 지정자는 타입 추론을 위해서도 사용됩니다. |
(since C23) |
파일 범위에서 const 이면서 extern 이 아닌 이름들은 C에서는 외부 링크를 가지지만(모든 파일 범위 선언의 기본값), C++에서는 내부 링크를 가집니다.
예제
#include <stdio.h> #include <stdlib.h> // static storage duration int A; int main(void) { printf("&A = %p\n", (void*)&A); // automatic storage duration int A = 1; // hides global A printf("&A = %p\n", (void*)&A); // allocated storage duration int* ptr_1 = malloc(sizeof(int)); // start allocated storage duration printf("address of int in allocated memory = %p\n", (void*)ptr_1); free(ptr_1); // stop allocated storage duration }
가능한 출력:
&A = 0x600ae4 &A = 0x7ffefb064f5c address of int in allocated memory = 0x1f28c30
참고문헌
- C23 표준 (ISO/IEC 9899:2024):
-
- 6.2.2 식별자의 링크 (p: 35-36)
-
- 6.2.4 객체의 저장 기간 (p: 36-37)
-
- 6.7.1 저장 클래스 지정자 (p: 97-100)
- C17 표준 (ISO/IEC 9899:2018):
-
- 6.2.2 식별자의 링크 (p: 29-30)
-
- 6.2.4 객체의 저장 기간 (p: 30)
-
- 6.7.1 저장 클래스 지정자 (p: 79)
- C11 표준 (ISO/IEC 9899:2011):
-
- 6.2.2 식별자의 링크 (p: 36-37)
-
- 6.2.4 객체의 저장 기간 (p: 38-39)
-
- 6.7.1 저장 클래스 지정자 (p: 109-110)
- C99 표준 (ISO/IEC 9899:1999):
-
- 6.2.2 식별자의 링크 (p: 30-31)
-
- 6.2.4 객체의 저장 기간 (p: 32)
-
- 6.7.1 저장 클래스 지정자 (p: 98-99)
- C89/C90 표준 (ISO/IEC 9899:1990):
-
- 3.1.2.2 식별자의 링크
-
- 3.1.2.4 객체의 저장 기간
-
- 3.5.1 저장 클래스 지정자
참고 항목
|
C++ 문서
for
Storage class specifiers
|