아, 표준 C에서는 문자열의 부동소수점 변환 오류를 이식성 있게 검사할 수 없는 모양이다

2 hours ago 3

표준 C의 문자열→부동소수점 변환 함수는 math_errhandling에 따라 오류 보고 방식이 달라지며, 언더플로 보고는 선택 사항이라 모든 구현에서 검출을 보장할 수 없음 POSIX는 표준 C와 달리 오버플로와 언더플로 발생 시 math_errhandling과 관계없이 errno를 ERANGE로 설정하도록 요구함 숫자로 변환할 수 없는 입력은 endptr == nptr 로 확인해야 하며, errno만 검사하면 POSIX 호환 구현 사이에서도 결과가 달라짐 strtod("x", nullptr) 호출 전 errno를 0으로 초기화하면 glibc는 0, musl은 EINVAL에 해당하는 22를 남기며, Linux 매뉴얼은 이 차이를 문서화하지 않음 오류 검사에서는 대상 표준과 구현의 보장을 구분해야 하며, errno를 ERANGE와 명시적으로 비교하고 부동소수점 예외를 사용할 때는 컴파일러 설정도 확인해야 함 math_errhandling은 문자열 변환 함수에도 적용됨 앞선 글은 math_errhandling 과 glibc/musl의 수학 오류 처리, 표준의 요구 사항을 살펴봄 이 매크로는 math.h 함수가 errno 방식인 MATH_ERRNO, 부동소수점 예외 방식인 MATH_ERREXCEPT 중 무엇을 지원하는지 나타냄 math.h에 속하지 않는 strtod, strtof, strtold, strtod32, strtod64, strtod128 도 이 매크로의 영향을 받음 표준 C 7.25.2.6p12는 기본 반올림 모드에서 오버플로가 발생할 때 다음 동작을 요구함 반환형과 부호에 따라 ±HUGE_VAL, ±HUGE_VALF, ±HUGE_VALL을 반환함 math_errhandling & MATH_ERRNO가 0이 아니면 errno를 ERANGE로 설정함 math_errhandling & MATH_ERREXCEPT가 0이 아니면 오버플로 부동소수점 예외를 발생시킴 언더플로가 발생하면 반환값의 절댓값은 해당 반환형의 최소 양의 정규화 수 이하여야 하지만, 오류 보고 여부는 구현 정의 사항임 MATH_ERRNO를 지원하더라도 ERANGE 설정 여부는 구현에 달려 있음 MATH_ERREXCEPT를 지원하더라도 언더플로 예외 발생 여부는 구현에 달려 있음 반환값만으로는 오류를 판별할 수 없으므로, 오버플로 검출에는 두 오류 보고 방식 중 하나가 필요함 호출 전에 feclearexcept(FE_OVERF...

Read Entire Article