C 전처리기

C preprocessor

C 전처리기C, Objective-C, C++, 다양한 포트란 언어와 같은 여러 컴퓨터 프로그래밍 언어위한 매크로 전처리기입니다. 전처리기는 헤더 파일 포함, 매크로 확장, 조건부 컴파일 및 라인 제어 기능을 제공합니다.

전처리 명령어의 언어는 C의 문법과 약하게만 연관되어 있기 때문에 다른 종류의 텍스트 파일을 처리하는 데 사용되기도 합니다.[1]

역사

이 전처리기는 1973년경 앨런 스나이더의 재촉으로 C에 도입되었으며, 또한 BCPLPL/I에서 사용할 수 있는 파일 포함 메커니즘의 유용성을 인정받아 도입되었습니다. 원래 버전은 파일 포함 기능과 간단한 문자열 교체 기능만 제공했습니다. #include 그리고. #define 매개 변수가 없는 매크로의 경우 각각. 그것은 얼마 지나지 않아 Mike Lesk에 의해, 그리고 John Reiser에 의해, 논쟁과 조건부 컴파일을 통해 매크로를 통합하기 위해 확장되었습니다.[2]

C 전처리기는 1959년 더글러스 이스트우드와 더글러스 매킬로이가 시작한 벨 연구소의 오랜 매크로 언어 전통의 일부였습니다.[3]

페이즈

전처리는 C 표준에 명시된 번역의 처음 4단계(8단계)에 의해 정의됩니다.

  1. 삼각형 교체: 전처리기는 삼각형 시퀀스를 나타내는 문자로 바꿉니다. 단계는 C++17의 단계에 따라 C23에서 제거됩니다.
  2. 선 스플라이싱: 탈출된 새 라인 시퀀스로 계속되는 물리적 소스 라인은 논리 라인을 형성하기 위해 스플라이싱됩니다.
  3. 토큰화: 전처리기는 결과를 전처리 토큰과 공백으로 나눕니다. 주석을 공백으로 대체합니다.
  4. 매크로 확장 및 지시 처리: 파일 포함 및 조건부 컴파일을 포함한 사전 처리 지시 행이 실행됩니다. 전처리기는 매크로를 동시에 확장하고 1999년 버전의 C 표준부터 처리합니다. _Pragma 오퍼레이터들

파일포함

전처리기의 가장 일반적인 용도 중 하나는 다른 소스 파일을 포함하는 것입니다.

# <stdio.h>  인트의 주된(공허한) {     활자로 인쇄한("안녕, 월드!\n");     돌아가다 0; } 

전처리기가 라인을 대체합니다. #include <stdio.h> 파일의 stdio 텍스트 내용과 함께.h'라고 선언합니다. printf() 다른 것들 중에서도 기능을 합니다.

이는 예를 들어 큰따옴표를 사용하여 작성할 수도 있습니다. #include "stdio.h". 파일 이름이 각괄호 안에 포함되어 있으면 파일이 경로를 포함한 표준 컴파일러에서 검색됩니다. 파일 이름이 큰따옴표 안에 포함되면 검색 경로가 현재 원본 파일 디렉토리를 포함하도록 확장됩니다. C 컴파일러와 프로그래밍 환경은 모두 프로그래머가 포함 파일을 찾을 수 있는 위치를 정의할 수 있는 기능을 갖추고 있습니다. 이는 명령 줄 플래그를 통해 도입할 수 있으며, 이 플래그는 makefile을 사용하여 매개 변수화할 수 있으므로 예를 들어 다른 운영 체제에 대해 다른 포함 파일 집합을 스왑할 수 있습니다.

관례에 따라 포함 파일의 이름은 .h 또는 .hpp 확장자로 지정됩니다. 그러나 이를 준수할 필요는 없습니다. .def 확장자가 있는 파일은 동일한 반복 내용을 확장할 때마다 여러 번 포함되도록 설계된 파일을 의미할 수 있습니다. #include "icon.xbm"XBM 이미지 파일(동시에 C 소스 파일)을 참조할 가능성이 높습니다.

#include 종종 가드 사용을 강제하거나 이중 포함을 방지합니다.

조건부 컴파일

다른 지시사항들은 #if, #ifdef, #ifndef, #else, #elif 그리고. #endif 조건부 컴파일에 사용할 수 있습니다. #ifdef 그리고. #ifndef 에 대한 단순한 약어. #if defined(...) 그리고. #if !defined(...).

#이프 버보스 >= 2   활자로 인쇄한("trace 메시지"); #endif 

Microsoft Windows를 대상으로 하는 대부분의 컴파일러는 암묵적으로 정의합니다. _WIN32.[4]이를[4] 통해 전처리기 명령을 포함한 코드를 Windows 시스템을 대상으로 할 때만 컴파일할 수 있습니다. 몇 개의 컴파일러가 정의합니다. WIN32 대신. 암묵적으로 정의하지 않는 컴파일러의 경우 _WIN32 macro, 컴파일러의 명령줄에 지정할 수 있습니다. -D_WIN32.

#ifdef __unix__ /* __unix__는 일반적으로 유닉스 시스템을 대상으로 하는 컴파일러에 의해 정의됩니다 */ # 포함하다 <언티스트.h> #elif 정의된 _WIN32 /* _WIN32는 일반적으로 32비트 또는 64비트 Windows 시스템을 대상으로 하는 컴파일러에 의해 정의됩니다 */ # 포함하다 <창문.h> #endif 

예제 코드는 매크로가 있는지 테스트합니다. __unix__ 정의되어 있습니다. 만약 그렇다면, 그 파일은 <unistd.h> 그런 다음 포함됩니다. 그렇지 않으면 매크로가 있는지 테스트합니다. _WIN32 대신 정의됩니다. 만약 그렇다면, 그 파일은 <windows.h> 그런 다음 포함됩니다.

좀더복잡한 #if 예제에서는 다음과 같은 연산자를 사용할 수 있습니다.

#!(defined _LP64__defined _LLP64__)가 정의된 경우 _WIN32 & & !defined _WIN64  // 32비트 시스템을 위해 컴파일 중입니다. #  // 64비트 시스템을 위해 컴파일 중입니다. #endif 

번역은 또한 다음을 사용하여 실패할 수 있습니다. #error 지시사항:

#RUBI_VERSION == 190인 경우 #error 1.9.0이 지원되지 않습니다. #endif 

매크로 정의 및 확장

매크로에는 객체형기능형의 두 가지 유형이 있습니다. 개체와 유사한 매크로는 매개 변수를 사용하지 않으며 함수와 유사한 매크로는 매개 변수 목록이 비어 있을 수 있습니다. 식별자를 각 유형의 매크로로 선언하는 일반 구문은 각각 다음과 같습니다.

#define <식별자> <교체토큰리스트>                    // 사물 같은 거시적인 #define <identifier>(<parameter list>)<교체토큰리스트>  // 함수 유사 매크로, 노트 매개변수 

함수와 같은 매크로 선언은 식별자와 첫 번째, 열림, 괄호 사이에 공백이 없어야 합니다. 공백이 있는 경우 매크로는 토큰 목록에 추가된 첫 번째 괄호부터 시작하는 모든 것이 개체와 유사한 것으로 해석됩니다.

매크로 정의는 다음을 사용하여 제거할 수 있습니다. #undef:

#undefect <identifier>                                              // 매크로 삭제 

식별자가 소스 코드에 나타날 때마다 대체 토큰 목록으로 대체되며, 이 목록은 비어 있을 수 있습니다. 함수형 매크로로 선언된 식별자의 경우, 다음 토큰이 매크로 호출의 인수 목록을 시작하는 왼쪽 괄호일 때만 대체됩니다. 논쟁이 있는 함수형 매크로의 확장을 위해 뒤따르는 정확한 절차는 미묘합니다.

예를 들어, 객체와 같은 매크로는 상수에 대한 기호 이름을 만들기 위한 좋은 프로그래밍 관행의 일부로 사용되었습니다.

#define PI 3.14159 

코드 전체에서 coding인 숫자 대신에. C와 C++ 모두에서 특히 숫자에 대한 포인터가 필요한 상황에서는 다음을 적용하는 것이 대안입니다. const 전역 변수의 한정자입니다. 그러면 값이 전처리기로 대체되지 않고 메모리에 저장됩니다.

함수와 유사한 매크로의 예는 다음과 같습니다.

#define RADTODEG(x) ((x) * 57.29578) 

이것은 필요한 경우 코드에 삽입할 수 있는 라디안-도 변환을 정의합니다. RADTODEG(34). 이것은 제자리에서 확장되므로 코드 전체에 상수에 의한 반복된 곱셈이 표시되지 않습니다. 여기서 매크로는 컴파일된 함수가 아닌 매크로임을 강조하기 위해 모두 대문자로 씁니다.

두번째 x 는 단일 값이 아닌 식일 때 잘못된 작업 순서가 발생할 가능성을 방지하기 위해 자체 괄호 쌍에 포함됩니다. 예를 들면, 그 표현은. RADTODEG(r + 1) 정확하게 확장하여 ((r + 1) * 57.29578); 괄호 없이, (r + 1 * 57.29578) 는 곱셈에 우선순위를 부여합니다.

마찬가지로 바깥쪽 괄호 쌍은 올바른 작동 순서를 유지합니다. 예를들면, 1 / RADTODEG(r) 로 확장됩니다. 1 / ((r) * 57.29578); 괄호 없이, 1 / (r) * 57.29578 나눗셈에 우선권을 부여합니다.

전개순서

함수와 유사한 매크로 확장은 다음 단계에서 이루어집니다.

  1. 문자열화 작업은 확장을 수행하지 않고 인수의 대체 목록을 텍스트로 표현하는 것으로 대체됩니다.
  2. 파라미터는 (확장을 수행하지 않고) 교체 목록으로 바뀝니다.
  3. 연결 작업은 결과 토큰을 확장하지 않고 두 피연산자의 연결 결과로 대체됩니다.
  4. 매개 변수에서 비롯된 토큰이 확장됩니다.
  5. 결과 토큰은 정상적으로 확장됩니다.

다음과 같은 놀라운 결과가 나타날 수 있습니다.

#정의 HE HI #정의 LLO _THERE #정의 HELLO "HI THERE" #define CAT(a,b) a##b #define XCAT(a,b) CAT(a,b) #define CALL(fn) fn(HE,LLO) 고양이(, LLO) // "HI THERE"는 정상적인 확장 전에 연결이 발생하기 때문입니다. XCAT(, LLO) // HI_THERE, 매개 변수("HE" 및 "LLO")에서 비롯된 토큰이 먼저 확장되기 때문입니다. 불러(고양이) // "HI THERE", 이것은 CAT(a,b)를 평가하기 때문입니다. 

특수 매크로 및 지시사항

특정 기호는 사전 처리 중 구현에 의해 정의되어야 합니다. 여기에는 다음이 포함됩니다. __FILE__ 그리고. __LINE__, 전처리기 자체에서 미리 정의한 것으로, 현재 파일과 행 번호로 확장됩니다. 예를 들어 다음과 같습니다.

// 매크로 디버깅을 통해 메시지 출처를 한눈에 파악할 수 있습니다. // 나쁘다, 나쁘다, #WHERESTR 정의 "[파일 %s, 행 %d]:" #WHEREARG __FILE__, _LINE__를 정의합니다. #defined DEBUGPRINT2(...) fprintf(stderr, __VA_)ARGS__) #defined DEBUGPRINT(_fmt, ...) DEBUGPRINT2(WHERSTR_fmt, WHERARG, __VA_)ARGS__) // 오어 // 좋습니다. #defined DEBUGPRINT(_fmt, ...) fprintf(stderr, "[file %s, line %d]: " _fmt, _FILE__, __LINE_, __VA_ARGS__)    디버그프린트("야, x=%d\n", x); 

값어치를 찍어내다 x, 오류 스트림에 대한 파일 및 행 번호가 선행되므로 메시지가 생성된 행에 빠르게 액세스할 수 있습니다. 참고: WHERESTR 인수는 뒤에 오는 문자열과 연결됩니다. 의 값. __FILE__ 그리고. __LINE__ 다음과 같이 조작할 수 있습니다. #line 지시의#line directive는 아래 줄의 줄 번호와 파일 이름을 결정합니다. 예:

#line 314 "pi.c" 활자로 인쇄한("line=%d 파일=%s\n", __LINE__, __FILE__); 

printf 함수를 생성합니다.

활자로 인쇄한("line=%d 파일=%s\n", 314, "pi.c"); 

소스 코드 디버거는 또한 다음과 같이 정의된 소스 위치를 말합니다. __FILE__ 그리고. __LINE__. 이를 통해 C가 컴파일러의 대상 언어로 사용될 때 완전히 다른 언어에 대한 소스 코드 디버깅이 가능합니다.번째 C 표준은 매크로가 __STDC__ 구현이 ISO 표준에 부합할 경우 1로 정의되고 그렇지 않을 경우 0으로 정의되며 매크로 __STDC_VERSION__ 구현에서 지원하는 표준 버전을 지정하는 숫자 리터럴로 정의됩니다. 표준 C++ 컴파일러는 다음을 지원합니다. __cplusplus 거시의 비표준 모드로 실행 중인 컴파일러는 이러한 매크로를 설정하지 않거나 다른 매크로를 정의하여 차이를 표시해야 합니다.

기타 표준 매크로는 다음을 포함합니다. __DATE__, 현재 날짜와 __TIME__, 시시각

C 표준의 두 번째 판인 C99는 다음에 대한 지원을 추가했습니다. __func__, 여기에는 함수 정의의 이름이 포함되어 있지만, 전처리기는 C의 문법에 구애받지 않으므로 함수에 대한 로컬 변수를 사용하여 컴파일러 자체에서 수행해야 합니다.

다양한 수의 인수(변수형 매크로)를 취할 수 있는 매크로는 C89에서는 허용되지 않지만, 여러 컴파일러에 의해 도입되었고 C99에서 표준화되었습니다. 버라이어티 매크로는 다음과 같은 다양한 수의 매개 변수를 사용하는 함수에 래퍼를 쓸 때 특히 유용합니다. printf, 예를 들어 경고 및 오류를 기록하는 경우.

C 전처리기의 잘 알려지지 않은 사용 패턴 중 하나는 X-Macros라고 알려져 있습니다.[5][6][7] X-Macro는 헤더 파일입니다. 일반적으로 이들은 기존의 ".h" 대신 확장자 ".def"를 사용합니다. 이 파일에는 "component macro"라고 할 수 있는 유사한 매크로 호출 목록이 포함되어 있습니다. 그런 다음 포함 파일을 반복적으로 참조합니다.

많은 컴파일러들이 표준이 아닌 추가 매크로를 정의하지만, 이러한 매크로들은 종종 제대로 문서화되지 않습니다. 이러한 매크로에 대한 일반적인 참조는 "표준, 컴파일러, 운영 체제, 하드웨어 아키텍처 및 기본 런타임 라이브러리를 식별하는 데 사용할 수 있는 다양한 사전 정의 컴파일러 매크로"를 나열하는 사전 정의 C/C++ 컴파일러 매크로 프로젝트입니다.

토큰 문자열화

# 연산자(스트링화 연산자 또는 문자열화 연산자)는 토큰을 C 문자열 리터럴로 변환하여 인용문이나 백슬래시를 적절히 피합니다.

예제:

#define줄 #s  스트레이트(p = "푸우"\n";) // 출력 "p = \"foo\\n\";" 스트레이트(\n)           // 출력 "\n" 

매크로 인수의 확장을 문자열화하려면 두 가지 수준의 매크로를 사용해야 합니다.

#define xstr(s) str(s) #define줄 #s #define foo 4  스트레이트 (푸우)  // 출력 "foo" xstr (푸우) // 출력 "4" 

매크로 인수를 추가 텍스트와 결합하고 모두 문자열화할 수 없습니다. 그러나 인접한 문자열 상수와 문자열화된 인수를 쓸 수 있습니다. 그러면 C 컴파일러는 인접한 문자열 상수를 모두 하나의 긴 문자열로 결합합니다.

토큰 연결

## 연산자("Token Pasting Operator")는 두 개의 토큰을 하나의 토큰으로 연결합니다.

예제:

#define DELACH_STRUCT_TYPE(이름) 유형 데프스트릭트 이름 ##_s name ##_t  DELACH_STRUCT_TYPE(g_객체); // 출력: typedef struct g_object_s g_object_t; 

사용자 정의 컴파일 오류

#error directive는 에러 스트림을 통해 메시지를 출력합니다.

#error "error message" 

이진 리소스 포함

C23은 다음을 소개할 것입니다. #embed 이진 리소스 포함에 대한 지시입니다.[8] 이를 통해 이미지와 같은 이진 파일을 유효한 C 소스 파일(XBM과 같은)이 아닌 프로그램에 포함할 수 있으며, 다음과 같은 외부 도구에 의한 처리를 필요로 하지 않습니다. xxd -i 그리고 MSVC에 길이 제한이 있는 문자열 리터럴을 사용하지 않습니다. 마찬가지로 xxd -i 명령어는 지정된 리소스의 데이터에 해당하는 정수의 쉼표로 구분된 목록으로 대체됩니다. 좀 더 정확하게, 유형의 배열인 경우 unsigned char 를 사용하여 초기화됩니다. #embed directive, 결과는 리소스가 fread를 사용하여 배열에 기록된 경우와 동일합니다(매개변수가 임베디드 요소 너비를 CHAR_B가 아닌 다른 것으로 변경하지 않는 경우).IT). 편리함은 차치하고, #embed 또한 컴파일러는 as-if 규칙 때문에 명령어를 전체 형식으로 확장하는 것을 생략할 수 있으므로 처리하기가 더 쉽습니다. 내장할 파일을 다음과 같은 방식으로 지정할 수 있습니다. #include, 쉐브론 사이 또는 따옴표 사이의 의미입니다. 또한 명령은 특정 매개 변수를 전달하여 파일 이름을 따르는 동작을 사용자 지정할 수 있습니다. C 표준은 다음과 같은 매개변수를 정의하며 구현은 자체적으로 정의할 수 있습니다.limit 포함된 데이터의 너비를 제한하기 위해 매개 변수를 사용합니다. 대부분 랜덤과 같은 "무한" 파일과 함께 사용하도록 되어 있습니다.prefix 그리고. suffix 매개 변수를 사용하면 프로그래머가 내장된 데이터에 접두사와 접미사를 지정할 수 있습니다. 이 접미사는 내장된 리소스가 비어 있지 않은 경우에만 사용됩니다. 마지막으로. if_empty 매개 변수는 리소스가 비어 있는 경우(파일이 비어 있거나 제한이 0인 경우) 전체 지시자를 바꿉니다. 예를 들어 C23의 표준 속성과 마찬가지로 모든 표준 매개변수를 이중 밑줄로 둘러쌀 수도 있습니다. __prefix__ 와 교환할 수 있습니다. prefix . 구현 정의 매개 변수는 속성 구문과 유사한 양식을 사용합니다(예: vendor::attr대괄호를 사용하지 않습니다. 모든 표준 매개 변수는 인수를 전달해야 하지만(예: 제한에는 너비가 필요함) 일반적으로 선택 사항이며 인수가 필요하지 않은 경우 괄호 집합도 생략할 수 있습니다. 이는 일부 구현 정의 매개 변수의 경우일 수 있습니다.

구현

모든 C, C++ 및 목표-C 구현은 전처리가 해당 언어들에 필요한 단계이며, ISO C 표준과 같은 이러한 언어들에 대한 공식 표준에 의해 그 동작이 기술되기 때문에 전처리를 제공합니다.

구현은 자체적인 확장과 편차를 제공할 수 있으며 서면 표준 준수 정도가 다를 수 있습니다. 이들의 정확한 동작은 호출 시 제공되는 명령줄 플래그에 따라 달라질 수 있습니다. 예를 들어, GNU C 전처리기는 특정 플래그를 제공함으로써 표준을 더욱 준수하도록 만들 수 있습니다.[9]

컴파일러별 프리프로세서 기능

#pragma 명령어는 컴파일러 고유의 명령어로, 컴파일러 공급업체가 자신의 목적을 위해 사용할 수 있습니다. 예를 들면, a. #pragma 는 종종 특정 오류 메시지의 억제, 힙 및 스택 디버깅 관리 등을 허용하는 데 사용됩니다. OpenMP 병렬화 라이브러리를 지원하는 컴파일러는 다음을 자동으로 병렬화할 수 있습니다. for 로 루프를 그리다 #pragma omp parallel for.

C99는 몇 가지 표준을 도입했습니다. #pragma 지시서, 형식을 취함 #pragma STDC ..., 부동 소수점 구현을 제어하는 데 사용됩니다. 대안적이고 거시적인 형태. _Pragma(...) 추가되었습니다.

  • 대부분의 구현은 삼각형을 지원하지 않거나 기본적으로 대체하지 않습니다.
  • 많은 구현체(예: GNU, Intel, Microsoft 및 IBM의 C 컴파일러 포함)는 출력에 경고 메시지를 출력하도록 비표준 명령을 제공하지만 컴파일 과정을 중단하지는 않습니다(C23[10] 및 C++23[11] 추가됩니다). #warning 이를 위한 기준)에 적합합니다. 일반적인 용도는 일부 오래된 코드의 사용에 대해 경고하는 것으로, 현재는 더 이상 사용되지 않으며 다음과 같은 호환성의 이유로 포함됩니다.
    // GNU, 인텔 및 IBM #경고 "ABC는 사용하지 마십시오. 대신 XYZ를 사용하세요." 
    // 마이크로소프트 #pragma 메시지("ABC를 사용하지 마십시오, 이는 권장되지 않습니다. 대신 XYZ를 사용합니다.") 
  • 일부 유닉스 프리프로세서들은 전통적으로 프로그래밍에 사용되는 주장들과 유사성이 거의 없는 "주장들"을 제공했습니다.[12]
  • GCC 제공 #include_next 같은 이름의 머리글을 연결합니다.[13]

언어별 전처리 기능

일부 언어의 사양에 의해 C 전처리기에 추가된 일부 전처리기 명령어가 있으며 해당 언어에 고유합니다.

  • 목표-C 전처리기는 #import, 그것은 마치 #include 파일을 한 번만 포함합니다. C에서 유사한 기능을 가진 일반적인 벤더 프래그마는 다음과 같습니다.
  • C++20 기준 C++에는 모듈에 대한 수입 및 모듈 지침이 있습니다.[14][15] 이 지침은 시작하지 않는 유일한 지침입니다. # 캐릭터, 대신에, 그들은 다음으로 시작합니다. import 그리고. module 각각 선택적으로 다음에 오는. export.

기타 용도

C 전처리기는 제공되는 컴파일러와 별도로 호출할 수 있기 때문에 다른 언어에서 별도로 사용할 수 있습니다. 주목할 만한 예로는 현재는 사용되지 않는 이미크 시스템과 포트란 전처리에 사용되는 것이 있습니다. 그러나 일반적인 목적의 전처리기와 같은 사용은 제한적입니다. 입력 언어는 충분히 C-like해야 합니다.[9] GNU 포트란 컴파일러는 특정 파일 확장자가 사용될 경우 포트란 코드를 컴파일하기 전에 자동으로 "transditional mode" (아래 참조) cpp를 호출합니다.[16] Intel은 비슷한 기능을 가진 ifort 컴파일러와 함께 사용할 수 있는 Fpp인 Fortran 전처리기를 제공합니다.[17]

CPP는 또한 대부분의 어셈블리 언어와 알골 유사 언어에서도 허용적으로 작동합니다. 이를 위해서는 언어 구문이 CPP 구문과 충돌하지 않아야 합니다. 이는 다음으로 시작하는 행이 없음을 의미합니다. # 그리고 cpp가 문자열 리터럴로 해석하여 무시하는 이중 따옴표는 그 외에는 통사적 의미가 없습니다. 일반적으로 "전통적인 모드"(ISOC 사전 프로세서처럼 작동)는 더 허용적이고 이러한 사용에 더 적합합니다.[18]

C 전처리기는 튜링 완전하지는 않지만 매우 근접합니다. 재귀적 계산은 지정할 수 있지만 수행된 재귀의 양에 대한 고정된 상한이 있습니다.[19] 그러나 C 전처리기는 범용 프로그래밍 언어로 설계되지도 않고 성능도 좋지 않습니다. C 전처리기는 재귀 매크로, 인용문에 따른 선택적 확장, 조건부 문자열 평가와 같은 일부 다른 전처리기의 기능이 없기 때문에 m4와 같은 보다 일반적인 매크로 프로세서에 비해 매우 제한적입니다.

참고 항목

참고문헌

  1. ^ C 전처리기를 사용한 범용 텍스트 전처리. 자바스크립트 기능
  2. ^ 리치 (1993)
  3. ^ "Bell SAP – SAP with conditional and recursive macros". HOPL: Online Historical Encyclopaedia of Programming Languages.
  4. ^ 미리 정의된 ANSI C 및 Microsoft C++ 구현 매크로 목록입니다.
  5. ^ 위르제니우스, 라스 C "유사한 데이터 유형 구현을 위한 사전 프로세서 트릭". 2011년 1월 9일 검색
  6. ^ Meyers, Randy (May 2001). "The New C: X Macros". Dr. Dobb's Journal. Retrieved 1 May 2008.
  7. ^ Beal, Stephan (August 2004). "Supermacros". Retrieved 27 October 2008. {{cite journal}}: 저널 인용 요구사항 journal= (도와주세요)
  8. ^ "WG14-N3017 : #embed – a scannable, tooling-friendly binary resource inclusion mechanism". open-std.org. 27 June 2022. Archived from the original on 24 December 2022.
  9. ^ a b "The C Preprocessor: Overview". Retrieved 17 July 2016.
  10. ^ "WG14-N3096 : Draft for ISO/IEC 9899:2023" (PDF). open-std.org. 1 April 2023. Archived (PDF) from the original on 2 April 2023.
  11. ^ "Working Draft, Standard for Programming Language C++" (PDF). 22 March 2023.
  12. ^ GCC 오래된 기능
  13. ^ "Wrapper Headers (The C Preprocessor)".
  14. ^ "N4720: Working Draft, Extensions to C++ for Modules" (PDF). Archived (PDF) from the original on 30 April 2019.
  15. ^ "P1857R1 – Modules Dependency Discovery".
  16. ^ "1.3 Preprocessing and conditional compilation". GNU Project.
  17. ^ "Using the fpp Preprocessor". Intel. Retrieved 14 October 2015.
  18. ^ "Overview (The C Preprocessor)". gcc.gnu.org. Having said that, you can often get away with using cpp on things which are not C. Other Algol-ish programming languages are often safe (Ada, etc.) So is assembly, with caution. -traditional-cpp mode preserves more white space, and is otherwise more permissive. Many of the problems can be avoided by writing C or C++ style comments instead of native language comments, and keeping macros simple.
  19. ^ "Is the C99 preprocessor Turing complete?". Archived from the original on 24 April 2016.

원천

외부 링크