OneDev

[C] #pragma(pack, once, warning) 본문

Language/C

[C] #pragma(pack, once, warning)

one_dev 2023. 8. 14. 15:24

#pragma 란?

#pragma컴파일러에게 특정 작업을 수행하도록 지시한다

#pragma 는 C 언어의 기본 키워드라고 보긴 힘들고, 컴파일러에 종속적인 키워드라고 보는 것이 맞지 싶다.

pragma를 사용하는 문법은 컴파일러 마다 다르고, 딱히 통일된 것이 없기 때문이다

 

#pragma 가 컴파일러에게 어떤 작업을 지시하는지는 #pragma 뒤에 오는 키워드에 따라 결정되는데, 

Microsoft Visual Studio 기준으로는 다음과 같은 것들이 있다

 

엄청....많다.....

각각의 키워드들에 대한 설명은 아래 링크를 참조하세요.

https://learn.microsoft.com/ko-kr/cpp/preprocessor/pragma-directives-and-the-pragma-keyword?view=msvc-170 

 

Pragma 지시문 및 __pragma 및 _Pragma 키워드

pragma MSVC(Microsoft Visual C 및 C++)에서 사용할 수 있는 지시문을 설명합니다.

learn.microsoft.com

 

이제 자주 쓰이는 키워드들에 대해 알아보자

 

◎ #pragma pack

#pragma pack구조체, 공용 구조체 및 클래스 멤버에 대한 압축 맞춤을 지정한다.

즉, 구조체를 몇 바이트 단위로 정렬할지 지정해줄 때 사용하는 키워드이다.

메모리 상에서 구조체의 크기는 컴파일러가 지정하는데, 대개 4의 배의 배수로 맞추게 된다.

예를 들면, 6바이트 짜리 구조체를 설계 했어도, 컴파일러가 4의 배수를 맞추기 위해 구조체의 크기를 8 바이트로 맞추는 일이 생긴다는 것이다 (필요없는 2바이트를 추가하면서 까지)

(이런 상황을 더블 워드 경계에 놓여있다 라고 합니다)

이런 상황은 하드웨어 간의 통신에서 문제를 일으킬 수 있다.

컴파일러로 하여금 구조체를 더블 워드 경계에 놓지 말라고 하고싶을 때 pragma pack 키워드를 이용한다

 

<< 예시 >>

 #pragma pack(1)  = "구조체를 1바이트 단위로 정렬해라" = "구조체의 크기가 1의 배수가 되게 해라"

 

※ 1 외에도 2, 4, 8, 16 등이 올 수 있고, 기본값(더블 워드 경계로 정렬)으로 설정하기 위해서는 #pragma pack(4) 로 하면 된다.

 

◎ #pragma once

#pragma once 키워드는 헤더파일이 여러번 포함되는 것을 막아준다. 

(여러번 include 하는 위험을 방지 +컴파일 시간도 절약)

물론  #ifndef 와 같은 전처리 지시자를 이용할 수도 있지만, #pragma once 를 이용하면 단순하게 끝낼 수 있다.

사용법 또한 간단한데, 헤더파일에 #pragma once 를 적어주면 된다

 

※ 다만 #pragma 관련 키워드들이 컴파일러 종속적이어서 어떤 컴파일러에서는 #pragma once가 지원되지 않을 수도 있다.

 

<< 예시 -  stdio.h 의 일부 >>

/***
 *stdio.h - definitions/declarations for standard I/O routines
 *
 *       Copyright (c) Microsoft Corporation. All rights reserved.
 *
 *Purpose:
 *       This file defines the structures, values, macros, and functions
 *       used by the level 2 I/O ("standard I/O") routines.
 *       [ANSI/System V]
 *
 *       [Public]
 *
 ****/
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef _INC_STDIO
#define _INC_STDIO

/* 내용 (생략) */

#endif /* _INC_STDIO */

 

◎ #pragma warning

#pragma warning 키워드를 이용해 경고메세지를 제어할 수 있다.

제어문 기능 예시
once : 번호 해당 경고를 한 번만 출력하게 해준다 #pragma warning(once : 4996)
default : 번호 원래 설정대로 되돌린다(기본값 복원) #pragma warning(default : 4996)
disable : 번호 해당 경고를 출력하지 않게 해준다 #pragma wraning(disable : 4996)
error : 번호 해당 경고를 에러로 만들어준다 #pragma wraning(error : 4996)
레벨 : 번호 해당 경고의 레벨(1~4)을 변경한다  
push /
(push, n)
모든 경고의 레벨을 저장한다.
n 이 있을 경우, 저장과 동시에 전역 경고 레벨(컴파일러에 표시되는 최대 경고 레벨) 을 n으로 변경한다
#pragma wraning(push) /
#pragma wraning(push, 4)
pop 스택에 마지막으로 저장된 경고 레벨을 복원한다 #pragma wraning(pop)

 

'Language > C' 카테고리의 다른 글

[C] volatile 키워드  (0) 2023.08.14
[C] typedef 키워드  (0) 2023.08.14
[C] 24. 매크로 함수 & 인라인(inline) 함수  (0) 2023.08.10
[C] memcpy  (0) 2023.08.01
[C] 23. 메모리 동적 할당(Dynamic Memory Allocation) - malloc, free  (0) 2023.07.31
Comments