Search
Duplicate
👾

[libft] errno와 매크로 사용

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
42cursus
Scrap
태그
9 more properties
결론부터 얘기하자면 errno을 사용해도 된다. NULL, LONG_MAX도 전부 다 써도 된다.
현재 만연한 분위기로 인해 디펜스를 해야할 수도 있지만 분위기가 바꼈으면 좋겠다.

errno

거의 모든 시스템 호출은 에러를 감지하면 외부 식별자 errno를 통해 오류 번호를 제공한다.
#include <errno.h> extern int * __error(); #define errno (* __error())
C
복사
여러 함수들의 man을 보면 ERRORS 섹션에 각 오류와 의미가 작성되어 있다.
man에 따르면 “-1이 반환되면 실패를 분석하여 그에 따른 조치를 취할 수 있다”고 되어 있다.
거의 모든 시스템 호출에서 사용하는 표준 방식이고 에러 핸들링이 깔끔해진다.
특히, 반환 값으로 성공/실패 여부를 알기 힘들 때 유용하게 사용할 수 있다.
설정되면 다른 오류가 발생될 때 까지 유지되므로 오류가 발생한 후에 검사를 해야 한다.
함수 A가 실패해서 errno가 설정되면, 함수 B를 성공해도 A의 errno는 계속 유지된다.

사용하면 안되는 이유와 그에 대한 반박

슬랙에 올라온 의견들을 보면 사용하면 안된다가 많아서 이를 하나하나 반박해보려고 한다.

코딩이 쉬워진다 (with ft_atoi)

“에러 핸들링이 편해지기 때문에 코딩이 쉬워진다”는 주장이다.
정확하게는 “errno를 사용하면 에러 핸들링이 깔끔해진다”이고 쉬워지는 건 아니다.
오히려 에러 핸들링을 하기 위해 추가되어야하는 부분이 생겨서 힘들 수도 있다.
ft_atoi를 통해 반박해보고자 하는데 설명하기 전에 앞서 관련 man 페이지부터 살펴보자.
[man] atoi
[man] strtol
ft_atoi의 반환값으로는 오버플로우를 알 수 없으며, 원본 함수는 errno를 사용하고 있다.
0 또는 -1이 반환 값이 변환이 성공해서인지 실패해서인지 알 수 없다.
원본에서는 errno 값이 ERNAGE 인지 확인한다.
평가 때 자주 나오는 소리가 “불가능하기 때문에 오버플로우는 처리하지 않아도 된다”이다.
errno를 쓸 수 있으면 처리 가능한 문제가 되기 때문에 다들 처리해야 한다…!! (난이도 상승)
처리 자체는 errno = ERANGE 만 설정하고 고정 값을 반환하면 끝난다.

매크로이다.

“표준 라이브러리의 매크로는 문제에서 사용허가했을때만 사용가능하다”는 주장이다.
프랑스 원문을 직접 번역해보면, 다른 내용이 나오는 것을 알 수 있다. 사용할 수 있다.
Vous pouvez utiliser les macros présentes dans les bibliothèques standards, si cette dernière est autorisée dans le projet ciblé. 표준 라이브러리가 대상 프로젝트에서 승인된 경우 표준 라이브러리에 있는 매크로를 사용할 수 있습니다.
추가로, 스페인 슬랙에서는 기존 전역 변수는 사용할 수 있다고 공지되어있다.
libft: se permite el uso de variables globales ya existentes (ejemplo: errno) libft: 기존 전역 변수 사용 허용(예: errno)

대상 프로젝트에서 승인되지 않았다.

“errno.h 는 프로젝트에서 명시적으로 허용되지 않았다는 “ 주장이다.
하지만, libft 과제를 보면 이름을 제외한 모든 것이 원본 함수와 동일해야 된다고 되어있다.
원본 함수들의 man을 확인해보면 ERRORS를 세팅하고 있다.

함수 매크로이다.

“errno 매크로가 내부적으로 함수를 호출한다”는 주장이다.
C99 표준 문서를 확인해보자.
[스크린샷] 표준 문서 7.5 Errors <errno.h>
표준 문서의 errno 7.5.2를 보면 다음과 같이 되어있다.
정수 상수 표현식이고, 매크로인지 식별자인지가 지정되지 않았다. (환경에 따라 다름)
2 The macros are EDOM EILSEQ ERANGE which expand to integer constant expressions with type int, distinct positive values, and which are suitable for use in #if preprocessing directives; and errno which expands to a modifiable lvalue169) that has type int, the value of which is set to a positive error number by several library functions. It is unspecified whether errno is a macro or an identifier declared with external linkage. If a macro definition is suppressed in order to access an actual object, or a program defines an identifier with the name errno, the behavior is undefined.
2 매크로는 EDOM EILSEQ ERANGE int 유형, 고유한 양수 값을 갖는 정수 상수 표현식으로 확장되며 #if 전처리 지시문에 사용하기에 적합합니다. 및 int 유형을 갖는 수정 가능한 lvalue169)로 확장되는 errno, 그 값은 여러 라이브러리 함수에 의해 양의 오류 번호로 설정됩니다. errno가 매크로인지 외부 연결로 선언된 식별자인지는 지정되지 않습니다. 실제 개체에 액세스하기 위해 매크로 정의가 표시되지 않거나 프로그램이 errno라는 이름으로 식별자를 정의하는 경우 동작이 정의되지 않습니다.
169에 대한 설명을 보면 현재 논란의 *errno() 함수 호출로 확장될 수 있다고 한다.
하지만, errno는 *errno()를 불러오기 위한 매크로이지 자체로서는 함수가 아니다.
또한, *errno() 함수는 extern int errno의 경우 스레드끼리 충돌이 날 수 있기 때문에 함수를 통해 스레드 안전성을 확보하기 위해 추가된 부분이지 원래의 목적이 아니다.
169) The macro errno need not be the identifier of an object. It might expand to a modifiable lvalue resulting from a function call (for example, *errno()). 169) 매크로 errno는 객체의 식별자일 필요는 없습니다. 함수 호출로 인해 수정 가능한 lvalue로 확장될 수 있습니다(예: *errno()).

허용 함수가 아니다.

minishell 에서는 errno가 허용함수로 등록되어 있다.
하지만, 그보다 앞선 C10 에서는 errno가 허용함수로 등록되어 있지 않고 변수로 명시되어 있다.
strerror 함수를 이용하기 위한 힌트 정도로 언급한 걸로 추측된다.
You may use the variable errno.
errno 변수를 사용할 수 있다.
[영어] C10 과제 hexdump
[불어] C10 과제 hexdump

프로젝트에서 언급되지 않았다.

“minishell이든 C10이든 errno가 언급이 되긴 했지만 libft는 없지 않느냐”라고 하면…
pipex에도 strerror이 있지만 errno가 언급되지는 않았다. strerror을 사용할 수 있는데 errno를 사용하지 못한다는 건 정말 의미없는 행동이라 생각한다.
libft에는 strerror은 없지만 얘네는 errno를 설정하는 함수들이라 strerrno가 필요없고, man에 ERRORS가 설정된다고 명시되어 있다.
간접적이나마 언급은 되어있다.
그래도 안된다고 할까봐 평가지를 일부 준비해왔다.
[스크린샷] 평가지
please comply with the following rules:
remain polite, courteous, respectful and constructive throughtout the evaluation process. The woll-being of the community depends on it.
identify with the student or group whose work is evaluated the possible dysfuncition in their project. tabke the time to discuss and debate the problems that may have been identified.
you must consider that there might be some differences in how your peer might have understood the project's instructions and the scope of its funcitonalities. always keep an open mind and grade them as honestly as possible. the pedagogy is useful only and only if the peer-evaluation is done seriously.
다음 규칙을 준수하십시오.
평가 과정 전반에 걸쳐 정중하고, 예의 바르며, 존중하고 건설적인 태도를 유지합니다. 지역 사회의 안녕이 달려 있습니다.
프로젝트에서 가능한 기능 장애로 평가되는 작업의 학생 또는 그룹과 확인합니다. 확인된 문제에 대해 토론하고 토론하는 시간을 가져보세요.
동료가 프로젝트 지침과 기능 범위를 이해하는 방식에 약간의 차이가 있을 수 있음을 고려해야 합니다. 항상 열린 마음을 유지하고 가능한 한 정직하게 등급을 매깁니다. 교수법은 동료 평가가 진지하게 수행되는 경우에만 유용합니다.
열린 마음을 가졌으면 좋겠지만 이 문구를 보고도 안된다고 하면 이제 더 반박할 거리는 없다.