안녕하세요!
오늘은 1980년의 C언어의 모습을 소개해보려 합니다.
버전 | 연도 | 주체 |
Traditional C | 1972 | Dennis Ritchie |
K & R C | 1978 | Kernighan & Dennis Ritchie |
ANSI C | 1989 | ANSI Committee |
ANSI/ISO C | 1990 | ISO Committee |
C99 | 1999 | Standardization Committee |
C11 | 2011 | ISO/IEC |
옛날 느낌 물씬!
아래의 코드를 살펴보시죠
#include <stdio.h>
func(a, b, c)
int a;
int b;
int c;
{
b = 40;
c = a + b;
printf("%d", c);
return (c);
}
main()
{
func(10);
return (0);
}
C
복사
⇒ 이걸 컴파일 해보면...
기본 반환타입이 int로 적용됩니다 라는 경고와 함께, 컴파일과 실행이 잘 되는 것을 볼 수 있습니다.
근데 왜 컴파일이 될까요?
그건 위 코드가 C99 표준 이전 스타일로 작성된 코드이기 때문입니다.
애플 오픈소스 사이트의 소스코드 중 오래된 코드들은 아래와 같이 생겼습니다.
위와 같은 코드 스타일을 K&R Syntax 라고 합니다.
C언어의 함수 선언/정의 방식은 표준화를 거쳐 조금씩 변화해왔습니다.
표준 이전의 코드, 즉 C89/ANSI C 이전의 함수 예시는 아래와 같습니다.
/* K&R definition of a function
K는 브라이언 커닝헨, R은 데니스 리치 */
foo(a)
{
a = 10;
// ...
return (a);
}
C
복사
이때, 프로그래머가 명시하지 않은 자료형은 모두 int 가 됩니다.
그래서 리턴값이 없는 함수를 정의하거나, 파라미터 타입을 설정하려면 다음과 같이 명시해줍니다.
void /* 반환 값 없음 */
bcopy(src0, dst0, length)
void *dst0; /* int로 값을 받은 뒤 void*로 설정 */
const void *src0; /* int로 값을 받은 뒤 const void*로 설정 */
{
register char *dst = dst0;
register const char *src = src0;
// ...
}
C
복사
이처럼 중괄호 밖에서 자료형을 명시하는 방식을 K&R function definition 이라고 하며, 명시하지 않은 모든 타입을 int로 받는 규칙을 "implicit int" rule 라고 부릅니다.
“자료형 명시가 없다면, 모두 int다."
int isalpha(int argument);
C
복사
오래 전에 구현된 C 라이브러리 함수 isalpha()나 memset()은 인자를 char 가 아닌 int 형으로 받고 있죠.
왜 int를 받을까 찾아보니, “오래된 함수여서 그렇다” 라는 스택 오버플로우 답변이 있었는데...
(참고링크 ) 스택 오버플로우 : “왜 memset이 char가 아닌 int를 받나요?”
바로 C99 표준 이전인 K&R 방식이라서 "implicit int" rule 이 적용되었기 때문이 아닐까 싶네요!
/* K&R style로 작성한 isalpha */
isalpha(c)
unsigned char c;
{
// ...
}
/* 이걸 C99 style로 바꾸면... */
int isalpha(int c)
{
unsigned char c_tmp = c;
// ...
}
C
복사
지금까지 1978년도의 C언어는 어땠는지 가볍게 소개해보았습니다.
다음 글에선 C언어의 모태가 된 BCPL 언어나, COBOL에 대해서 한번 다뤄보겠습니다.
읽어주셔서 감사합니다.
•
참고 자료
[블로그] K&R 문법에 대한 블로그 설명
[스택 오버플로우] “왜 memset이 char가 아닌 int를 받나요?”
[스택오버플로우] K&R 함수 선언
[블로그] C언어 기본 산술연산 자료형
추가 링크 모음