programing

log(10.0)는 컴파일할 수 있지만 log(0.0)는 정의되지 않은 참조로 컴파일할 수 없습니까?

telebox 2023. 6. 16. 21:41
반응형

log(10.0)는 컴파일할 수 있지만 log(0.0)는 정의되지 않은 참조로 컴파일할 수 없습니까?

다음 C 소스 코드의 경우:

#include <math.h>

int main(void)
{
    double          x;

    x = log(0.0);

    return 0;
}

로 할 때gcc -lm내가 받은 것:

/tmp/ccxxANVH.o: In function `main':
a.c:(.text+0xd): undefined reference to `log'
collect2: error: ld returned 1 exit status

하지만, 제가 대신한다면,log(0.0)와 함께log(10.0)성공적으로 컴파일할 수 있습니다.

저는 이것을 잘 이해하지 못합니다. 수학적으로 말이 되든 안 되든, 그들은 컴파일을 해야 하기 때문입니다. 구문 오류는 없습니다.누가 이것을 설명해 줄 수 있습니까?

혹시 모르니까, 나의.gcc -v출력:

Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

이 질문은 지속적인 접기에 관한 것이지만 제안된 중복 질문은 누락된 연결 라이브러리에 관한 것입니다.

gcc에서는 많은 경우 기본 제공 기능을 사용할 수 있습니다. 설명서에는 다음과 같이 나와 있습니다.

이러한 기능의 대부분은 특정한 경우에만 최적화됩니다. 특정한 경우에 최적화되지 않으면 라이브러리 기능에 대한 호출이 발생합니다.

그러로므.gcc에 대해 가 없지만, 이 기능을 사용할 때는 수학 라이브러리에 대해 설명합니다.log(0)정의되지 않았습니다. 아마도 힘이 될 것입니다.gcc부작용이 있으므로 런타임에 평가합니다.

초안 C99 표준 섹션을 살펴보면,7.12.1 제4항의 오류 조건 처리(광산 강조):

수학적 결과의 크기가 유한하지만 너무 커서 지정된 유형의 객체에서 특별한 반올림 오차 없이 수학적 결과를 표현할 수 없는 경우 부동 결과가 오버플로됩니다.부동 결과가 오버플로하고 기본 반올림이 적용되거나 수학적 결과가 유한 인수(예: log(0.0))의 정확한 무한인 경우 함수는 반환 유형에 따라 매크로 HUGH_VAL, HUGH_VALF 또는 HUGH_VALL의 값을 반환합니다.함수의 정확한 값과 동일한 부호를 사용하여, 정수math_errhandling & MATH_ERRNO가 0이 아닐 경우, 정수 errno는 ERANGE 값을 획득합니다. 정수 식 math_errhandling & MATH_ERREXCET가 0이 아닐 경우,수학적 결과가 정확한 무한대인 경우 ''solute-by-zero'' 부동 소수점 예외가 발생하고 그렇지 않은 경우 ''solute'' 부동 소수점 예외가 발생합니다.

다음을 사용하여 실시간 예를 볼 수 있습니다.-S표준횡단을 생성하기 위한 플래그grep log에 대한 전화를 걸러 내다log.

의 경우에는log(0.0)다음 지침이 생성됩니다(라이브 참조).

call    log

그러나 의 경우에는log(10.0)아니요.call log명령이 생성됩니다(라이브 참조).

우리는 보통 예방할 수 있습니다.gcc-fno-built-in 플래그를 사용하여 내장 기능을 사용하는 것이 내장 기능이 사용되고 있는지 여부를 테스트하는 더 빠른 방법일 수 있습니다.

참고:-lm 소스 파일 뒤로 이동해야 합니다. 예를 들어, (연결된 답변에서 제외)main.c수학 라이브러리가 필요한 경우 다음을 사용합니다.

 gcc main.c -lm 

컴파일은 괜찮습니다, 링커 스위치만 있으면 됩니다.-lm그것이 누락되었습니다.

두 번째 버전은 아마도 컴파일하고 링크합니다.gcc대체log(10.0)상수를 사용하므로 수학 라이브러리에 대한 호출이 필요하지 않습니다.두 번째 경우에는 결과가 수학적으로 정의되지 않으며 평가 결과 도메인 오류가 발생합니다.이 경우 도메인 오류 처리가 런타임에 다를 수 있으므로 식을 상수로 대체할 수 없습니다.

C-표준(초안)에서 인용한 내용:

도메인 오류에서 함수는 구현 정의 값을 반환합니다. 정수 식 math_errhandling & MATH_ERRNO가 0이 아닌 경우 정수 식 errno가 값 EDOM을 가져옵니다. 정수 식 math_errhandling & MATH_ERREXCT가 0이 아닌 경우 ''invalid'' 부동 소수점 예외가 발생합니다.

그래서 평가가.log(0.0)값을 반환하는 결과를 초래합니다.HUGE_VAL(아닙니다.NAN이전에 주장한 바와 같이) 또는 부동 소수점 예외입니다.

EDIT: 받은 코멘트를 바탕으로 답변을 수정하고 C-standard의 설명에 링크를 추가했습니다.

언급URL : https://stackoverflow.com/questions/24294578/log10-0-can-compile-but-log0-0-cannot-with-undefined-reference

반응형