C 전처리기
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
C 전처리기는 1973년경 C 언어에 도입된 기능으로, 파일 포함, 매크로 확장, 조건부 컴파일 등을 수행한다. C 표준의 번역 단계 중 처음 4단계를 담당하며, 트라이그래프 대체, 라인 결합, 토큰화, 매크로 확장 및 지시어 처리를 거친다. `#include`를 사용하여 다른 파일의 내용을 현재 위치에 포함시키고, `#if`, `#ifdef` 등의 지시어를 통해 조건부로 코드를 컴파일하거나 제외할 수 있다. `#define`을 사용하여 매크로를 정의하고 확장하며, 특수한 매크로인 `__FILE__`, `__LINE__` 등을 통해 디버깅 정보를 제공한다. C23 표준에서는 바이너리 리소스 포함을 위한 `#embed` 지시어가 도입될 예정이다. C 전처리기는 C, C++, Objective-C 등에서 사용되며, 컴파일러별로 다양한 확장 기능을 제공한다. 또한 다른 언어에서도 사용될 수 있지만, 입력 언어가 C와 유사해야 한다.
더 읽어볼만한 페이지
- 매크로 프로그래밍 언어 - TeX
TeX는 도널드 커누스가 개발한 수학, 과학, 공학 분야의 고품질 문서 출력을 위한 조판 시스템이며, 수학 수식 조판에 특화된 매크로 시스템과 높은 확장성을 제공한다. - 매크로 프로그래밍 언어 - M4 (프로그래밍 언어)
M4는 1977년 데니스 리치와 브라이언 커니건이 개발한 매크로 프로세싱 프로그래밍 언어이며, 텍스트 재사용, 파일 포함, 문자열 조작 등 다양한 기능을 제공하고 튜링 완전성을 갖춘 언어이다. - C 프로그래밍 언어 - C (프로그래밍 언어)
C는 하드웨어 제어와 이식성이 뛰어난 고급 절차적 프로그래밍 언어로서, 다양한 분야에서 사용되며 후속 언어에 영향을 주었고, 성능과 효율성이 높지만 안전성 문제 개선이 필요한 언어이다. - C 프로그래밍 언어 - 헤더 파일
헤더 파일은 프로그래밍 언어에서 코드 재사용성, 모듈화, 컴파일 시간 단축에 기여하며 함수 프로토타입, 변수 선언 등을 포함하고 `#include` 지시어로 소스 코드에 포함되어 사용되는 파일이다.
C 전처리기 | |
---|---|
기본 정보 | |
종류 | 컴퓨터 프로그램, 컴파일러 |
개발자 | 여러 개발자 |
발표일 | 1972년 |
최신 버전 | GNU cpp 13.2 (2023년 8월 2일) |
상태 | 활발 |
추가 정보 | |
운영체제 | 크로스 플랫폼 |
언어 | C, C++, Objective-C |
종류 | 전처리기 |
라이선스 | GNU GPL (일부) |
2. 역사
C 전처리기는 1973년경 앨런 스나이더(Alan Snyder)의 제안과 BCPL 및 PL/I에서 사용 가능한 파일 포함 메커니즘의 유용성을 인식하여 C에 도입되었다. 초기 버전은 파일 포함과 단순 문자열 교체만 제공했으며, 매개변수가 없는 매크로를 위해 `#include`와 `#define`을 사용했다. 이후 마이크 레스크(Mike Lesk)와 존 라이저에 의해 매개변수가 있는 매크로 및 조건부 컴파일 기능을 포함하도록 확장되었다.[2]
전처리(preprocessor)는 C 표준에 명시된 여덟 단계의 "번역 단계" 중 처음 네 단계로 정의된다.
`#include` 지시어는 다른 소스 파일을 현재 파일에 포함시켜 하나의 파일처럼 컴파일되도록 하는 기능이다. 보통 IDE 개발 환경에서는 프로젝트 단위로 여러 파일을 관리하고 컴파일하여 실행 파일을 생성하는데, 이때 `#include`를 사용하여 서로 다른 파일 간에 함수, 변수 선언 등을 연결한다.
`#if`, `#ifdef`, `#ifndef`, `#else`, `#elif`, `#endif`는 특정 조건에 따라 코드 블록을 컴파일하거나 제외하는 조건부 컴파일 기능을 제공한다.[4] 조건이 맞지 않으면 해당 코드는 컴파일되지 않아 마치 소스 코드 자체가 없는 것과 같은 효과를 낸다.
`#define` 지시어는 특정 식별자를 다른 토큰으로 대체하는 매크로를 정의하는 데 사용된다. 이러한 매크로는 객체 유사 매크로와 함수 유사 매크로 두 가지 유형이 있다. 객체 유사 매크로는 주로 상수에 이름을 붙여 코드의 가독성을 높이는 데 사용된다.[21] 예를 들어, `#define PI 3.14159`와 같이 정의하면 코드 내에서 `PI`라는 식별자를 사용할 때마다 `3.14159`로 대체된다. 이렇게 하면 숫자 자체를 사용하는 것보다 의미를 명확하게 전달할 수 있다.
C 전처리기는 1959년 더글러스 이스트우드와 더글러스 맥길로이(Douglas McIlroy)에 의해 시작된 벨 연구소(Bell Labs)의 긴 매크로 언어 전통의 일부였다.[3]
3. 번역 단계
1. 트라이그래프 대체: 전처리기는 트라이그래프 시퀀스를 해당 문자로 대체한다. 이 단계는 C23에서 C++17의 단계를 따라 제거될 예정이다.[1]
2. 라인 결합: 이스케이프 문자로 이스케이프된 개행 문자 시퀀스로 계속되는 물리적 소스 라인은 논리적 라인을 형성하기 위해 '결합'된다.[1]
3. 토큰화: 전처리기는 결과를 '전처리 토큰'과 공백 문자로 나눈다. 주석은 공백으로 대체한다.[1]
4. 매크로 확장 및 지시어 처리: 파일 포함 및 조건부 컴파일을 포함한 전처리 지시어 라인이 실행된다. 전처리기는 매크로를 동시에 확장하고, 1999년 버전의 C 표준부터는 `_Pragma` 연산자를 처리한다.[1]
4. 파일 포함
예시:
```cpp
#include
int main(void)
{
printf("Hello, world!\n");
return 0;
}
```
위 코드에서 `#include
`#include` 지시어는 `<>` (꺾쇠 괄호) 또는 `""` (큰따옴표)를 사용하여 파일 이름을 감쌀 수 있다.
C 컴파일러 및 프로그래밍 환경은 include 파일을 찾을 위치를 지정하는 기능을 제공하며, 이는 makefile을 통해 매개변수화된 명령줄 플래그를 사용하여 설정할 수 있다. 이를 통해 운영 체제에 따라 다른 include 파일 집합을 사용할 수 있다.[1]
관례상 include 파일은 `.h` 또는 `.hpp` 확장자를 사용하지만, 반드시 지켜야 하는 것은 아니다. `.def` 확장자는 여러 번 포함되도록 설계된 파일을 나타내며, `#include "icon.xbm"`과 같이 XBM 이미지 파일(C 소스 파일이기도 함)을 참조할 수도 있다.[1]
`#include`를 사용할 때는 이중 포함을 방지하기 위해 `#include` 가드 또는 `#pragma once`를 사용하는 것이 일반적이다.[1]
5. 조건부 컴파일
예시:
```cpp
#if VERBOSE >= 2
print("trace message");
#endif
```
위 코드에서 `VERBOSE` 값이 2보다 크거나 같으면 `print("trace message");` 코드가 컴파일되고, 그렇지 않으면 컴파일되지 않는다. `VERBOSE` 값은 미리 정의되어 있어야 한다.
조건부 컴파일을 활용하면 다양한 환경에 맞게 코드를 컴파일할 수 있다.
```cpp
#ifdef __unix__ /* __unix__는 일반적으로 유닉스 시스템을 대상으로 하는 컴파일러에 의해 정의됩니다 */
# include
#elif defined _WIN32 /* _WIN32는 일반적으로 32 또는 64비트 윈도우 시스템을 대상으로 하는 컴파일러에 의해 정의됩니다 */
# include
#endif
```
위 코드는 운영체제가 UNIX 환경(`__unix__`가 정의된 경우)이면 `
`#if`와 `defined`를 함께 사용하면 더 복잡한 조건부 컴파일도 가능하다.
```cpp
#if !(defined __LP64__ || defined __LLP64__) || defined _WIN32 && !defined _WIN64
// 우리는 32비트 시스템을 위해 컴파일하고 있습니다.
#else
// 우리는 64비트 시스템을 위해 컴파일하고 있습니다.
#endif
```
`#error` 지시어를 사용하면 컴파일을 강제로 실패시킬 수 있다.
```cpp
#if RUBY_VERSION == 190
#error 1.9.0은 지원되지 않습니다.
#endif
```
위 코드는 `RUBY_VERSION`이 190이면 컴파일 오류를 발생시킨다.
윈도우를 대상으로 하는 대부분의 컴파일러는 `_WIN32` 매크로를 암묵적으로 정의한다.[4] 이를 이용하면 윈도우 시스템을 대상으로 할 때만 코드가 컴파일되도록 할 수 있다. `_WIN32` 매크로를 정의하지 않는 컴파일러의 경우 `-D_WIN32` 옵션을 사용하여 컴파일러 명령줄에서 지정할 수 있다.
6. 매크로 정의 및 확장
함수 유사 매크로는 함수처럼 인수를 받아 더 복잡한 변환을 수행할 수 있다.[22] 예를 들어, `#define RADTODEG(x) ((x) * 57.29578)`와 같이 정의하면 `RADTODEG(34)`와 같은 코드는 `((34) * 57.29578)`로 확장된다. 이렇게 하면 코드를 간결하게 유지하고 반복을 줄일 수 있다.
`#undef` 지시어를 사용하면 정의된 매크로를 제거할 수 있다.[21][22] `#undef PI`와 같이 사용하면 `PI`에 대한 매크로 정의가 제거된다.
C++에서는 `const` 한정자나 `constexpr` 키워드를 사용하여 객체 유사 매크로와 유사한 기능을 수행할 수 있다.[5] `constexpr`는 컴파일 시간에 값을 계산하도록 지정하여 매크로처럼 사용할 수 있게 해준다.
C 전처리기는 1973년경 앨런 스나이더(Alan Snyder)의 제안으로 C에 도입되었으며, 초기에는 파일 포함과 단순 문자열 교체 기능만 제공했다.[2] 이후 마이크 레스크(Mike Lesk)와 존 라이저에 의해 기능이 확장되었다. C 전처리기는 더글러스 맥길로이(Douglas McIlroy) 등이 참여한 벨 연구소의 매크로 언어 전통을 계승한 것이다.[3]
매크로를 정의할 때는 연산자 우선순위로 인한 오류를 방지하기 위해 주의해야 한다. 매크로 인자와 전체 표현식을 괄호로 묶는 것이 일반적인 방법이다. 예를 들어 `RADTODEG(r + 1)`은 `((r + 1) * 57.29578)`로 확장되어 올바른 계산 결과를 얻을 수 있다.
6. 1. 확장 순서
함수형 매크로 확장은 다음 단계로 수행된다.
1. 문자열화 연산자는 인수의 대체 목록의 텍스트 표현으로 대체된다. (확장 수행하지 않음).
2. 매개변수는 대체 목록으로 대체된다.(확장 수행하지 않음).
3. 연결 연산자는 두 피연산자의 연결된 결과로 대체된다. (결과 토큰을 확장하지 않음).
4. 매개변수에서 파생된 토큰이 확장된다.
5. 결과 토큰은 정상적으로 확장된다.
이는 놀라운 결과를 초래할 수 있다.
```cpp
#define HE HI
#define LLO _THERE
#define HELLO "HI THERE"
#define CAT(a,b) a##b
#define XCAT(a,b) CAT(a,b)
#define CALL(fn) fn(HE,LLO)
CAT(HE, LLO) // "HI THERE", 연결은 일반 확장 전에 수행된다.
XCAT(HE, LLO) // HI_THERE, 매개변수("HE" 및 "LLO")에서 파생된 토큰이 먼저 확장된다.
CALL(CAT) // "HI THERE", 이는 CAT(a,b)로 평가되기 때문이다.
7. 특수 매크로 및 지시어
C 전처리기는 프로그램 실행에 필요한 여러 특수 매크로와 지시어를 제공한다.
- `__FILE__`과 `__LINE__`: 이 매크로들은 각각 현재 소스 파일의 이름과 줄 번호를 나타낸다. 주로 디버깅 목적으로 사용되며, 오류 메시지를 출력할 때 파일 이름과 줄 번호를 함께 표시하여 문제 발생 위치를 쉽게 찾도록 도와준다.[6]
```cpp
#define DEBUGPRINT(_fmt, ...) fprintf(stderr, "[file %s, line %d]: " _fmt, __FILE__, __LINE__, __VA_ARGS__)
DEBUGPRINT("x = %d\n", x);
```
- `#line`: 이 지시어는 `__FILE__`과 `__LINE__`의 값을 변경한다. 예를 들어 `#line 314 "pi.c"`는 이후 코드의 줄 번호를 314로, 파일 이름을 "pi.c"로 설정한다. 이는 다른 언어로 작성된 코드를 C 코드로 변환할 때 유용하다.[6]
```cpp
#line 314 "pi.c"
printf("line=%d file=%s\n", __LINE__, __FILE__); // 출력: line=314 file=pi.c
```
- `__STDC__`, `__STDC_VERSION__`, `__cplusplus`: 이 매크로들은 각각 컴파일러가 표준 C를 따르는지 (`__STDC__`), 지원하는 표준 버전은 무엇인지 (`__STDC_VERSION__`), C++ 컴파일러인지 (`__cplusplus__`)를 나타낸다. 이를 통해 특정 표준에 맞는 코드를 작성하거나, C와 C++ 간 호환성을 확보할 수 있다.[6]
- X-Macros: 이 패턴은 헤더 파일에 매크로 호출 목록을 정의하고, 이 파일을 여러 번 포함시켜 코드 중복을 줄이는 기법이다. 주로 확장자가 `.def`인 파일에 정의된다.[6][7][8]
7. 1. 토큰 문자열화
`#` 연산자 ('''문자열화 연산자''' 또는 '''스트링화 연산자'''라고도 함)는 토큰을 C 문자열 리터럴로 변환하며, 따옴표나 백슬래시를 적절하게 이스케이프 처리한다.예시:
```cpp
#define str(s) #s
str(p = "foo\n";) // 출력: "p = \"foo\\n\";"
str(\n) // 출력: "\n"
```
매크로 인수의 확장을 문자열화하려는 경우, 두 단계의 매크로를 사용해야 한다.
```cpp
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo) // 출력: "foo"
xstr (foo) // 출력: "4"
```
매크로 인수는 추가 텍스트와 결합된 다음 문자열화될 수 없다. 그러나 일련의 인접한 문자열 상수와 문자열화된 인수는 작성할 수 있으며, C 컴파일러는 모든 인접한 문자열 상수를 하나의 긴 문자열로 결합한다.
7. 2. 토큰 연결
`##` 연산자 ("토큰 접합 연산자"라고도 함)는 두 개의 토큰을 하나의 토큰으로 연결한다.```cpp
#define DECLARE_STRUCT_TYPE(name) typedef struct name##_s name##_t
DECLARE_STRUCT_TYPE(g_object); // 출력 결과: typedef struct g_object_s g_object_t
8. 사용자 정의 컴파일 오류
`#error` 지시어는 컴파일 오류를 발생시키고 지정된 메시지를 출력한다.
```c
#error "오류 메시지"
```
이 코드는 컴파일 시 "오류 메시지"라는 오류 메시지를 출력하고 컴파일을 중단시킨다. 주로 특정 조건이 충족되지 않았을 때 컴파일을 중단시키기 위해 사용된다.
9. 바이너리 리소스 포함
C23은 바이너리 리소스 포함을 위한 `#embed` 지시자를 도입할 예정이다.[9] 이를 통해 바이너리 파일(예: 이미지)을 프로그램에 포함할 수 있다. `#embed` 지시자는 지정된 리소스의 데이터에 해당하는 쉼표로 구분된 정수 목록으로 대체된다. 이는 `unsigned char` 유형의 배열이 `#embed` 지시자를 사용하여 초기화된 경우, fread를 사용하여 리소스를 배열에 쓴 것과 동일한 결과가 나타나는 것과 같다.
포함할 파일은 `#include`와 동일한 방식으로 지정할 수 있으며, 산형 괄호 또는 따옴표로 묶을 수 있다. 이 지시자는 파일 이름 뒤에 오는 동작을 사용자 정의하기 위해 특정 매개변수를 전달할 수 있도록 한다. C 표준은 다음과 같은 매개변수를 정의한다.
- `limit`: 포함된 데이터의 너비를 제한한다. 주로 urandom과 같은 "무한" 파일에 사용하기 위한 것이다.
- `prefix` 및 `suffix`: 포함된 데이터에 대한 접두사 및 접미사를 지정할 수 있으며, 이는 포함된 리소스가 비어 있지 않은 경우에만 사용된다.
- `if_empty`: 리소스가 비어 있는 경우(파일이 비어 있거나 0의 제한이 지정된 경우 발생) 전체 지시자를 대체한다.
모든 표준 매개변수는 C23의 표준 속성과 마찬가지로 이중 밑줄로 묶을 수도 있다. 예를 들어, `__prefix__`는 `prefix`와 상호 교환이 가능하다.
10. 구현체
C, C++, Objective-C 구현은 모두 전처리기를 제공하며, 이는 해당 언어들의 필수적인 단계이다. 전처리기의 동작은 ISO C 표준과 같은 언어의 공식 표준에 의해 설명된다.[10]
구현은 자체적인 확장 및 변형을 제공할 수 있으며, 표준 준수 정도는 다를 수 있다. 정확한 동작은 호출 시 제공되는 명령줄 플래그에 따라 달라질 수 있다. 예를 들어, GNU C 전처리기는 특정 플래그를 통해 표준 준수를 높일 수 있다.[10]
10. 1. 컴파일러별 전처리기 기능
`#pragma` 지시어는 컴파일러 관련 지시어로, 컴파일러 제작자가 자체적인 목적으로 사용할 수 있다. 예를 들어, `#pragma`는 특정 오류 메시지 표시를 억제하고, 힙 및 스택 디버깅 등을 관리하는 데 자주 사용된다. OpenMP 병렬화 라이브러리를 지원하는 컴파일러는 `#pragma omp parallel for`를 사용하여 `for` 루프를 자동으로 병렬화할 수 있다.C99는 부동 소수점 구현을 제어하는 데 사용되는 `#pragma STDC ...` 형식의 몇 가지 표준 `#pragma` 지시어를 도입했다. 매크로와 유사한 형태인 `_Pragma(...)`도 추가되었다.
- 많은 구현에서 삼중 문자열을 지원하지 않거나 기본적으로 대체하지 않는다.
- 많은 구현(예: GNU, Intel, Microsoft 및 IBM의 C 컴파일러)은 출력에 경고 메시지를 출력하지만 컴파일 프로세스를 중지하지 않는 비표준 지시어를 제공한다(C23[11] 및 C++23[12]은 이 목적으로 표준에 `#warning`을 추가한다). 일반적인 사용법은 호환성을 위해 포함된 더 이상 사용되지 않는 오래된 코드의 사용에 대해 경고하는 것이다. 예를 들면 다음과 같다.
- * GNU, Intel 및 IBM
```
#warning "ABC는 더 이상 사용되지 않으므로 사용하지 마십시오. 대신 XYZ를 사용하십시오."
```
- * Microsoft
```
#pragma message("ABC는 더 이상 사용되지 않으므로 사용하지 마십시오. 대신 XYZ를 사용하십시오.")
```
- 일부 유닉스 전처리기에서는 프로그래밍에서 사용되는 어설션과는 거의 유사성이 없는 "어설션"을 전통적으로 제공했다.[13]
- GCC는 동일한 이름의 헤더를 연결하기 위해 `#include_next`를 제공한다.[14]
10. 2. 언어별 전처리기 기능
Objective-C 전처리기는 `#include`와 유사하지만 파일을 한 번만 포함하는 `#import`를 가지고 있다. C에서 유사한 기능을 가진 일반적인 공급업체 프래그마는 `#pragma once`이다.C++는 C++20부터 모듈을 위한 `import` 및 `module` 지시어를 가지고 있다.[15][16] 이 지시어들은 `#` 문자로 시작하지 않는 유일한 지시어이다. 대신, 선택적으로 `export`가 앞에 올 수 있으며, 각각 `import`와 `module`로 시작한다.
11. 기타 용도
C 전처리기는 컴파일러와 별도로 호출할 수 있어 다른 언어에서도 사용할 수 있다. 주목할 만한 예로는 현재는 사용되지 않는 imake 시스템과 포트란 전처리에 사용된 경우가 있다.[10] GNU 포트란 컴파일러는 특정 파일 확장자를 사용하면 포트란 코드를 컴파일하기 전에 자동으로 "전통 모드"(ISO C 이전의 C 전처리기처럼 작동) cpp를 호출한다.[17] 인텔은 ifort 컴파일러와 함께 사용할 수 있는 포트란 전처리기인 fpp를 제공하며, 이는 비슷한 기능을 제공한다.[18]
CPP는 대부분의 어셈블리 언어 및 알골 계열 언어와도 문제없이 작동한다. 이를 위해서는 언어 구문이 CPP 구문과 충돌하지 않아야 하는데, 이는 `#`으로 시작하는 줄이 없어야 하고, cpp가 문자열 리터럴로 해석하여 무시하는 큰따옴표가 그 외의 구문적 의미를 가지지 않아야 한다. "전통 모드"(ISO C 이전의 C 전처리기처럼 작동)는 일반적으로 더 관대하며 이러한 사용에 더 적합하다.[19]
C 전처리기는 튜링 완전성을 만족하지 않지만, 거의 근접한다. 재귀적인 계산을 지정할 수 있지만, 수행되는 재귀의 양에 고정된 상한이 있다.[20] 그러나 C 전처리기는 일반적인 목적의 프로그래밍 언어처럼 설계되지 않았으며, 성능도 좋지 않다. C 전처리기는 재귀 매크로, 인용에 따른 선택적 확장, 조건부 문자열 평가와 같은 다른 전처리기의 기능을 가지고 있지 않으므로, m4와 같은 보다 일반적인 매크로 프로세서에 비해 매우 제한적이다.
참조
[1]
URL
General-purpose text preprocessing with the C preprocessor. Featuring JavaScript
https://gist.github.[...]
[2]
Harvtxt
Ritchie
1993
[3]
Encyclopedia
Bell SAP – SAP with conditional and recursive macros
https://hopl.info/sh[...]
[4]
URL
List of predefined ANSI C and Microsoft C++ implementation macros.
http://msdn.microsof[...]
[5]
웹사이트
General Constant Expressions for System Programming Languages, Proceedings SAC '10
http://www.stroustru[...]
2010-03-22
[6]
웹사이트
C "Preprocessor Trick For Implementing Similar Data Types"
http://liw.iki.fi/li[...]
2011-01-09
[7]
Journal
The New C: X Macros
http://www.ddj.com/c[...]
2001-05
[8]
Journal
Supermacros
http://wanderinghors[...]
2004-08
[9]
웹사이트
WG14-N3017 : #embed – a scannable, tooling-friendly binary resource inclusion mechanism
https://www.open-std[...]
2022-06-27
[10]
웹사이트
The C Preprocessor: Overview
https://gcc.gnu.org/[...]
2016-07-17
[11]
웹사이트
WG14-N3096 : Draft for ISO/IEC 9899:2023
https://www.open-std[...]
2023-04-01
[12]
웹사이트
Working Draft, Standard for Programming Language C++
https://open-std.org[...]
2023-03-22
[13]
URL
GCC Obsolete features
https://gcc.gnu.org/[...]
[14]
웹사이트
Wrapper Headers (The C Preprocessor)
https://gcc.gnu.org/[...]
[15]
웹사이트
N4720: Working Draft, Extensions to C++ for Modules
https://isocpp.org/f[...]
[16]
웹사이트
P1857R1 – Modules Dependency Discovery
https://www.open-std[...]
[17]
웹사이트
1.3 Preprocessing and conditional compilation
https://gcc.gnu.org/[...]
GNU Project
[18]
웹사이트
Using the fpp Preprocessor
https://software.int[...]
Intel
2015-10-14
[19]
웹사이트
Overview (The C Preprocessor)
https://gcc.gnu.org/[...]
[20]
웹사이트
Is the C99 preprocessor Turing complete?
https://stackoverflo[...]
[21]
웹인용
Object-like macros
http://gcc.gnu.org/o[...]
2012-11-25
[22]
웹인용
Function-like macros
http://gcc.gnu.org/o[...]
2012-11-25
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com