Search
Duplicate
🤔

어차피 char로 해석할건데 왜 int형 매개변수로 받을까? (ft. memset())

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
C
역사
라이브러리
Scrap
태그
libft
c언어
C99
9 more properties

⇒ 분명 실행할때는 char로 해석하는데 매개변수는 int인, 요상꾸리 아리송한 함수들은 implicit funcion declaration(암시적 함수 선언)이 가능했던 시절, 그러니까 아~~~주 오래전의 구닥다리 함수이다.

어차피 char로 해석하게 되는데 매개변수가 int인 알쏭달쏭한 함수들(memset(), memchr()….etc)이 Libft 과제에 나온다.

prototype 선언 안해도 함수의 호출이 가능했던 놀라운 시절의 유산

오래된 C 표준에서는 함수를 호출할 때, 호출하기에 앞서 함수 원형(prototype)이 선언되지 않은 함수를 호출할 수 있었다. (애초에 프로토타입이라는게 존재하지 않았다!!!!)
이때 원형 선언이 없는 함수는 int func(); /* 매개변수 목록 없음*/과 같은 꼴로 간주되며(implicit declaration, 암묵적 선언) 그러한 함수들에 전달되는 각 인자들은 default argument promotion이라는 과정을 거치게 된다.
예를 들어, default argument promotion이 적용되는 상황에서는 인자로 char 데이터를 전달하려고 시도하면 int로 promoted되어서 전달된다.
나중에 프로토타입 함수 선언이 도입되었지만, 표준 함수들의 레거시 동작과 이미 컴파일된 레거시 라이브러리와 맞추어야했기 때문에, 프로토타입 도입 이전 케케묵은 옛날 함수들의 매개변수는 int가 되어야했다.
현재 이론적으로 memset()과 같은 함수들에 대해 int 대신 char를 받도록 ‘수정할 수 있긴’하다. 그렇지만 그렇게 하기 위해선 높은 비용이 들것이고 또 코드를 수정함으로써 얻는 이익이 거의 없기 때문에 굳이 수정하지 않고 있다.
하필 int형으로 default argument promotion되는 이유는, int형은 실행 환경에서 가장 효율적으로 다룰 수 있는 정수형으로 정의되어 있으며 따라서 어떤 실행 환경에서도 가장 합리적이고 빠른 속도를 보장하기 때문이다. (사실 default 데이터형으로써 사용할 목적으로 int를 이렇게 정의내린 것이다.)
함수 원형 없이 어떻게 매개변수를 넘겨 함수를 호출할 수 있었냐고? "걍 원래 그랬었으니까"

implicit function declaration (암시적 함수 선언)

… 이 기능은 최신 C언어 표준(C99 등)에서는 빠진 것으로 알고 있습니다. 함수를 호출하려면 반드시 그 전에 선언하라는 거죠. 예전에는 함수 선언이 없었어도 컴파일러가 대충 찍어서 넘겨줬지만, 그에 따른 득(=프로그래머가 코딩할 때 약간 덜 귀찮음)보다는 실(=미정의 동작에 빠진 프로그램을 디버깅하는데 들어가는 상당한 노력)이 더 크다는 겁니다. …
함수 원형(prototype)이라는게 없었던 옛날에는 함수를 호출하기에 앞서 원형을 선언해주지 않아도 함수 호출이 가능했다. C89 이전 표준에서는 자체적으로 암묵적(implicit) 선언을 해주었기 때문이다.
원형이 없는 함수들은 int func(); /* 매개변수 목록 없음*/과 같은 꼴로 간주되었으며 그러한 함수들에 전달되는 각 인자들은 default argument promotion을 거치게된다.
프로토타입이 도입되면서, 함수를 호출하기에 앞서 원형을 선언해주지 않는다면 호출을 못하게 막게되었고 따라서 현재(C99 표준 이후)는 implicit declaration는 불가하다.
함수 원형을 선언하지 않고 사용했을 때 나오는 error인 implicit declaration of function 가 바로 이것이다!!!
default argument promotion (기본 인자 승격) 함수 호출이 원형 선언의 지배를 받지 않는 경우(implicit declaration 등), 혹은 원형 선언이 보이더라도 가변 인자를 갖는 경우, 인자(argument)에 적용되는 일정한 변환 규칙이다.
→ 인자와 매개변수의 데이터형에 관심을 덜 써도 정의된 행동을 보장받을 수 있도록한다. (즉 프로그래머가 코드 작성할 때 쫌 편해짐)
1. int 보다 작은 정수 타입은 int형으로 변환한다.
2. float형은 double형으로 변환한다.
3. 나머지 인자는 그대로 전달한다.
(즉 함수의 return 및 parameter의 타입을 모두 int, double형으로 변환)