그냥 재미있어보여서 시작하게 되었습니다.
시작하게 된 배경이나 그런 게 딱히 없어서, 바로 본 내용으로 들어가도록 하겠습니다.
extern long read(int fd, void *buf, unsigned long count);
extern long write(int fd, const void *buf, unsigned long count);
int main() {
char buffer[100];
long bytesRead;
bytesRead = read(0, buffer, sizeof(buffer)-1);
if (bytesRead > 0) buffer[bytesRead] = '\\0';
const char msg[] = "Hello, C without #include!\\n!";
write(1, msg, sizeof(msg)-1);
}
여기서 extern 이라는 키워드는 다른 파일의 전역 변수나 함수를 가져오는 데에 사용되는 키워드입니다. read 함수와 write 함수는 libc에서 기본적으로 제공하는 함수이므로 extern 키워드로 가져올 수 있다고 합니다.
이 코드는 C++로는 컴파일이 안 되기 때문에, C언어만 사용해야 할 것 같(다고 생각했)습니다.
저걸 입출력을 받을 때마다 하기에는 너무나도 불편할 것 같았기 때문에, 좀 더 편하게 사용할 수 있도록 입출력 함수를 새로 만들어줬습니다.

char 의 배열로 만들어줬습니다. 이름은 각각 rBuf, wBuf입니다.getc는 아직 입력을 받지 않았거나 입력 버퍼가 꽉 찬 경우 read 함수를 사용해 버퍼에 입력을 받고, 버퍼의 다음 문자를 반환하는 역할을 합니다.getll과 geti는 getc를 이용해 정수를 입력받고 그 값을 반환하는 역할을 합니다.flush는 출력 버퍼에 저장된 문자들을 출력한 후 출력 버퍼를 비우는 역할을 합니다.puts와 putc 는 출력 버퍼에 문자(들)을 넣는 역할을 하고, puti나 putll등의 함수들은 정수를 문자열로 변환해 출력 버퍼에 넣는 역할을 합니다.extern void* malloc(unsigned long size);
extern void free(void* ptr);
를 하면 사용할 수 있다고 합니다. malloc의 인자가 unsigned long long으로 고쳐져야 하긴 하지만, 작동하는 것을 확인했습니다. 다행히 계속 진행할 수 있게 되었습니다.
여기까지 하고 “그럼 extern으로 사용하고 싶은 모든 함수를 불러오면 되는 거 아닌가?” 라는 생각이 들었고, 시도해본 결과, scanf나 printf 같은 것도 불러올 수 있었습니다. 그러나, 그러면 재미가 없겠죠. extern으로 불러오는 건 최대한 적게 사용하도록 합시다.
또한, extern "C" 를 사용하면 C++을 사용할 수 있다는 사실도 알게 되었습니다. 사실 C로 진행하는 게 더 재미있을 것 같아 그렇게 하려고 했으나, 모든 자료형에 대한 vector를 각각 구현해야 한다는 것을 깨닫고 빠르게 포기했습니다.
extern "C"를 사용해야 하는 이유는 C언어와 C++에서 함수를 저장하는 방식이 다르기 때문이라고 합니다. 더 자세한 내용은 안 찾아봤어요.따라서, 문제를 다음과 같이 다시 정의하려고 합니다.
<aside> 💡
#include와 #import를 사용하지 않고, extern 키워드를 최소한으로 사용해 PS하기
</aside>
C++에는 new와 delete 키워드가 있으므로, extern 사용 횟수를 절반으로 줄일 수 있게 되었습니다. 기쁘네요.
순수 C로만 짠 코드가 좀 아까워서, 여기에 남기려고 합니다.
C99로 컴파일되는 A+B 코드