IT이야기

왜 수학 도서관을 C로 링크해야 하죠?

cyworld 2022. 6. 13. 22:28
반응형

왜 수학 도서관을 C로 링크해야 하죠?

★★★★★★★★★★★★★★★를 포함하면,<stdlib.h> ★★★★★★★★★★★★★★★★★」<stdio.h>때 C 프로그램에 .<math.h> 를 사용합니다.-lm예를 들어 다음과 같습니다.

gcc test.c -o test -lm

그 이유는 무엇입니까?다른 라이브러리는 링크하지 않고 수학 라이브러리를 명시적으로 링크해야 하는 이유는 무엇입니까?

stdlib.h ★★★★★★★★★★★★★★★★★」stdio.h 실시하다libc.so (오류)libc.a(의 경우)는디폴트로 를 들어 ('스태틱 링크-lc지정되었습니다).는 GCC와의 할 수 .-nostdlib ★★★★★★★★★★★★★★★★★」-nodefaultlibs★★★★★★★★★★★★★★★★★★.

이 계산은 다음에서 기능합니다.math.h 실시하다libm.so (오류)libm.a링크의 ) 및 """"""""""""를 참조해 주세요.libm는 디폴트로 링크되어 있지 않습니다..libm/libc둘 중 누구도 설득력이 없어

은 C++ 입니다.libstdc++에는 「」가 필요합니다.libm GCC를 GCC」 「C++」 「C+」).g++이.libm링크되어 있습니다.

아무도 고치려 하지 않는 말도 안 되는 역사적 관행 때문이다.로 하는 모든 파일로 이을 피할 수 있을 뿐만 각 C의 POSIX는 시간과 할 수 .각각은.so에서 file system operations를 file linked 에는relocations등 되어 있습니다.

와 1개의 라이브러리 내에 -lm,-lpthread,-lrt link to 등)..afiles) POSIX에 대해 설명합니다.

주의: C 자체는 컴파일러의 기동 방법에 대해 아무것도 규정하지 않았기 때문에 POSIX에 대해 말하고 있습니다. 그냥 치료하면 죠.gcc -std=c99 -lm컴파일러가 적합 동작을 위해 호출되어야 하는 구현 고유의 방식입니다.

C는 오래된 언어이며 FPU는 비교적 최근의 현상이라는 점에 유의하십시오.C는 8비트 프로세서에서 처음 보았는데 32비트 정수 연산도 힘들었습니다.이러한 구현의 대부분은 부동소수점 연산 라이브러리조차 없었습니다.

최초의 68000 머신(Mac, Atari ST, Amiga)에서도 부동소수점 코프로세서는 종종 고가의 애드온이었습니다.

부동소수점 계산을 하려면 꽤 큰 도서관이 필요했어요그리고 수학은 더디게 될 것이다.수레를 거의 사용하지 않았군요.정수나 축척 정수로 모든 것을 수행하려고 했습니다.네가 수학을 포함시켜야 할 때, 너는 이를 악물었다.이를 피하기 위해 직접 근사치 및 룩업 테이블을 작성하는 경우가 많습니다.

트레이드오프는 오랫동안 존재했다.때때로 "패스트매스"라 불리는 경쟁적인 수학 패키지들이 있었다.수학에 대한 가장 좋은 해답은 무엇입니까?정확하지만 느린 거?정확하지 않지만 빠른가?트리거 함수에 대한 큰 표?코프로세서가 컴퓨터에 확실히 탑재되고 나서야 대부분의 구현이 명확해졌습니다.저는 지금 어딘가에 프로그래머가 있을 거라고 생각합니다. 임베디드 칩을 개발하고 있습니다. 수학 문제를 해결하기 위해 수학 라이브러리를 가져올지 말지 고민하고 있습니다.

그래서 수학이 표준이 아니었다.많은 또는 대부분의 프로그램이 하나의 플로트를 사용하지 않았습니다.만약 FPU가 항상 주변에 있었고 플로트 및 더블이 항상 작동 비용이 낮았다면 "스투매스"가 있었을 것입니다.

것은벌벌 벌벌벌다다 명기할 -lm더이상.아마 많은 사람들이 그것에 대해 불평한다면, 그것은 고쳐질 것이다.(구분을 계속하는 유지보수가 매우 완고한 것은 분명하지만, 나는 그것을 진심으로 믿지 않는다.)

설명은 다음과 같습니다.

하고 있고 수학 함수를 포함하고 있는 math.h 수학 를 명시적으로 하려면 , 을 -lm이이 그들의 까다롭고 은 표준 flag 만의 수학 이다. 이 특별한 분리의 이유는 수학자들이 그들의 수학이 계산되는 방식에 대해 매우 까다롭고 그들은 수학 함수의 표준 구현 대신 그들만의 구현을 사용하고 싶어하기 때문이다.으로 묶은 경우libc.a그렇게 하는 것은 불가능할 것이다.

[편집]

하지만 내가 이것에 동의하는지는 잘 모르겠어.예를 들어 다음과 같은 기능을 제공하는 도서관이 있다면sqrt()표준 라이브러리 앞에 전달하면 Unix 링커가 버전을 가져가는 거죠?

모든 라이브러리는 다음과 같습니다.stdio.h그리고.stdlib.h에 실장되어 있다libc.so또는libc.a디폴트로는 링커에 의해 링크됩니다.의 라이브러리libc.so컴파일 중에 자동으로 연결되며 실행 파일에 포함됩니다.
그렇지만math.h에 실장되어 있다.libm.so또는libm.a와는 별개이다libc.so디폴트로는 링크되지 않기 때문에 프로그램을 컴파일 할 때 수동으로 링크해야 합니다.gcc을 사용하여-lm플래그를 설정합니다.

gnu gcc 팀은 다른 헤더 파일과 분리되도록 설계했지만 다른 헤더 파일은 기본적으로 링크되지만 math.h 파일은 링크되지 않습니다.

14.3번 항목을 읽어보십시오. 원한다면 모두 읽어보실 수 있습니다.math.h가 링크되어야 하는 이유
기사를 보세요.math.h를 gcc로 링크해야 하는 이유는 무엇입니까?
사용법을 확인하세요: 라이브러리 사용

외부 라이브러리와의 링크에 대한 자세한 내용은 "GCC 소개 - 외부 라이브러리와의 링크"를 참조하십시오.라이브러리가 표준 라이브러리(stdio 등)의 멤버인 경우에는 컴파일러(실제 링커)에 링크하도록 지정할 필요가 없습니다.

편집: 다른 답변과 코멘트를 읽어본 결과, libc.a 레퍼런스와 링크되어 있는 libm 레퍼런스는 왜 두 개가 분리되어 있는지에 대해 많은 것을 알 수 있었습니다.

'libm.a'(수학 라이브러리)의 함수 중 많은 수는 'math.h'에 정의되지만 libc.a에는 없습니다.혼란스러울 수도 있지만 경험의 법칙은 다음과 같습니다.C 라이브러리에는 ANSI가 반드시 존재해야 하는 함수가 포함되어 있기 때문에 ANSI 함수만 사용하는 경우에는 -lm이 필요하지 않습니다.반대로 libm.a'에는 더 많은 기능이 포함되어 있으며, FP 오류 발생 시 matherr 콜백 및 몇 가지 대체 동작 표준 준수 등의 추가 기능이 지원됩니다.자세한 내용은 섹션 libm을 참조하십시오.

주의:-lm일부 C 산술 함수를 사용하는 경우에도 항상 지정할 필요는 없습니다.

예를 들어 다음과 같은 간단한 프로그램을 들 수 있습니다.

#include <stdio.h>
#include <math.h>

int main() {

    printf("output: %f\n", sqrt(2.0));
    return 0;
}

다음 명령어를 사용하여 컴파일하여 정상적으로 실행할 수 있습니다.

gcc test.c -o test

gcc 7.5.0(Ubuntu 16.04) 및 gcc 4.8.0(CentOS 7)에서 테스트.

여기 게시물에는 다음과 같은 설명이 있습니다.

호출하는 연산 함수는 컴파일러 내장 함수에 의해 구현됩니다.

다음 항목도 참조하십시오.

왜냐면time()기타 기능은 다음과 같습니다.builtinC 라이브러리에 정의되어 있습니다(libc) 자체와 GCC는 항상 libc에 링크합니다.-ffreestanding컴파일 옵션하지만 수학 함수는libmgcc에 의해 암묵적으로 링크되지 않습니다.

stdio는 기본적으로 gcc가 링크되는 표준 C 라이브러리의 일부입니다.

산술 함수 구현은 기본적으로 연결되지 않은 별도의 libm 파일에 있으므로 -lm을 지정해야 합니다.덧붙여서, 그 헤더 파일과 라이브러리 파일 사이에는 관계가 없습니다.

ephemient가 말했듯이 C 라이브러리 libc는 기본적으로 링크되어 있으며 이 라이브러리에는 stdlib.h, stdio.h 및 기타 표준 헤더 파일의 구현이 포함되어 있습니다.덧붙이자면, 「GCC의 개요」에 의하면, C 의 기본적인 「Hello World」프로그램의 링커 커맨드는 다음과 같습니다.

ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o 
/usr/lib/crti.o /usr/libgcc-lib /i686/3.3.1/crtbegin.o
-L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh -lc 
-lgcc -lgcc_eh /usr/lib/gcc-lib/i686/3.3.1/crtend.o /usr/lib/crtn.o

C 라이브러리를 링크하는 세 번째 행의 옵션 -lc에 주목해 주세요.

제멋대로인 것 같아요.어딘가에 선을 그어야 합니다(기본 라이브러리와 지정해야 하는 라이브러리).

같은 기능을 가진 다른 제품으로 교환할 수 있는 기회가 있습니다만, 그렇게 하는 것은 그다지 흔하지 않다고 생각합니다.

편집: (내 코멘트에서):원래 CC와의 하위 호환성을 유지하기 위해 gcc가 이렇게 한다고 생각합니다.cc가 이렇게 하는 이유는 빌드 시간 때문입니다. cc는 현재보다 훨씬 적은 전력을 가진 기계를 위해 작성되었습니다.많은 프로그램에는 부동소수점 연산이 없으며 일반적으로 사용되지 않는 모든 라이브러리를 기본값에서 제외했을 수 있습니다.UNIX OS의 빌드 시간과 그에 수반되는 툴이 원동력이었다고 생각합니다.

stdlib.h 또는 stdio.h를 입력하면 링크할 필요가 없지만 컴파일할 때 링크해야 합니다.

stdlib.h,stdio.h헤더 파일입니다.당신은 당신의 편의를 위해 그것들을 포함합니다.적절한 라이브러리에서 링크하는 경우에만 사용할 수 있는 기호를 예측합니다.구현은 라이브러리 파일에 있습니다.이것이 함수가 실제로 존재하는 부분입니다.

포함하여math.h모든 산술 함수에 접근하기 위한 첫 번째 단계일 뿐입니다.

또한 링크할 필요가 없습니다.libm그 기능을 사용하지 않는 경우라도#include <math.h>이것은, 컴파일러에게 있어서 심볼에 관한 정보 제공에 지나지 않습니다.

stdlib.h,stdio.h에서 이용 가능한 기능을 참조하다libc사용자가 직접 할 필요가 없도록 항상 링크되어 있습니다.

전혀 사용하지 않는 앱의 성능을 조금 향상시키는 방법이라고 생각합니다.이것에 대한 제 생각은 이렇습니다.

x86 OS(다른 OS도 포함)는 컨텍스트 스위치에 FPU 상태를 저장해야 합니다.그러나 대부분의 OS는 앱이 처음으로 FPU를 사용하려고 시도한 후에만 이 상태를 저장/복원합니다.

이 외에도 함수 라이브러리에는 라이브러리가 로드될 때 FPU를 정상적인 기본 상태로 설정하는 몇 가지 기본 코드가 있을 수 있습니다.

따라서 어떤 연산 코드도 링크하지 않으면 이러한 현상이 발생하지 않으므로 OS는 FPU 상태를 저장/복원할 필요가 없으므로 컨텍스트 스위치의 효율이 약간 향상됩니다.

그냥 추측일 뿐이에요.

편집: 일부 코멘트에 대한 응답으로 비FPU 케이스에도 동일한 기본 전제가 적용됩니다(libm을 사용하지 않는 앱의 성능을 약간 향상시키는 것을 전제로 합니다).

예를 들어, C의 초기에는 리클리였던 소프트 FPU가 있는 경우.그 후 libm을 분리하면 대량의 큰 코드(사용의 경우는 느린 코드)가 불필요하게 링크되는 것을 방지할 수 있습니다.

또한 정적 링크만 사용할 수 있는 경우 실행 파일 크기를 유지하고 컴파일 시간을 줄일 수 있다는 동일한 인수가 적용됩니다.

언급URL : https://stackoverflow.com/questions/1033898/why-do-you-have-to-link-the-math-library-in-c

반응형