(방법) 특정 함수 호출을 인라인으로 연결할 수 있습니까?
프로그램의 여러 부분에서 호출되는 기능이 있다고 가정해 보겠습니다.또한 성능에 매우 민감한 코드 섹션(예: 수천만 번 반복되는 루프 및 각 마이크로초가 중요한 루프)에 있는 해당 기능에 대한 특별한 호출이 있다고 가정해 보겠습니다.로 사용할 수 ?gcc
나의 경우) 다른 것들을 줄이지 않고 특정한 단일 함수 호출을 줄입니까?
편집: 이 질문은 gcc(또는 다른 컴파일러)가 함수에 대한 모든 호출을 인라인화하도록 강제하는 것이 아니라 컴파일러가 함수에 대한 특정 호출을 인라인화하도록 요청하는 것에 관한 것입니다.
C에서는 (C++와 반대로) 함수에 인라인을 적용해야 한다고 제안하는 표준 방법이 없습니다.공급업체별 확장만 가능합니다.
내가 알기로는 컴파일러는 항상 모든 인스턴스를 인라인화하려고 하므로 이 함수를 한 번만 사용합니다.
원본:
int MyFunc() { /* do stuff */ }
다음으로 변경:
inline int MyFunc_inlined() { /* do stuff */ }
int MyFunc() { return MyFunc_inlined(); }
을 긋고 에는 이제인으표위서치에시할을 하세요.MyFunc_inlined()
참고: 위의 "인라인" 키워드는 gcc가 인라인을 강제로 적용하기 위해 사용하는 구문에 대한 자리 표시자일 뿐입니다.H2CO3의 삭제된 답변을 신뢰하려면 다음과 같습니다.
static inline __attribute__((always_inline)) int MyFunc_inlined() { /* do stuff */ }
번역 단위당 인라인을 사용할 수 있지만 통화당 인라인을 사용할 수는 없습니다.비록 이것은 질문에 대한 답이 아니며 추악한 속임수이지만, 그것은 C 표준에 부합하고 관련된 것으로서 흥미로울 수 있습니다.
요령은 사용하는 것입니다.extern
인라인을 사용하지 않을 위치와 인라인이 필요한 위치를 정의합니다.
예:
$ cat func.h
int func();
$ cat func.c
int func() { return 10; }
$ cat func_inline.h
extern inline int func() { return 5; }
$ cat main.c
#include <stdio.h>
#ifdef USE_INLINE
# include "func_inline.h"
#else
# include "func.h"
#endif
int main() { printf("%d\n", func()); return 0; }
$ gcc main.c func.c && ./a.out
10 // non-inlined version
$ gcc main.c func.c -DUSE_INLINE && ./a.out
10 // non-inlined version
$ gcc main.c func.c -DUSE_INLINE -O2 && ./a.out
5 // inlined!
속성 비준속예성표)을 사용할 .__attribute__(always_inline))
( GCC에 extern inline
정의, 의존하는 대신-O2
.
그나저나, 그 트릭은 glibc에서 사용됩니다.
C에서 함수를 강제로 인라인화하는 전통적인 방법은 함수를 전혀 사용하지 않고 매크로와 같은 함수를 사용하는 것이었습니다.이 방법은 항상 함수에 인라인을 연결하지만 매크로와 같은 함수에 몇 가지 문제가 있습니다.예:
#define ADD(x, y) ((x) + (y))
printf("%d\n", ADD(2, 2));
C99 표준에서 C에 추가된 inline 키워드도 있습니다.특히 Microsoft의 Visual C 컴파일러는 C99를 지원하지 않기 때문에 해당 (비참한) 컴파일러와 함께 사용할 수 없습니다.인라인은 컴파일러에 함수의 인라인화를 원하는 것을 암시할 뿐 보장하지는 않습니다.
GCC에는 컴파일러가 함수를 인라인화해야 하는 확장자가 있습니다.
inline __attribute__((always_inline)) int add(int x, int y) {
return x + y;
}
이를 더 깨끗하게 하려면 매크로를 사용할 수 있습니다.
#define ALWAYS_INLINE inline __attribute__((always_inline))
ALWAYS_INLINE int add(int x, int y) {
return x + y;
}
특정 통화에서 강제로 인라인화할 수 있는 기능을 직접 사용할 수 있는 방법을 모르겠습니다.그러나 다음과 같은 기술을 결합할 수 있습니다.
#define ALWAYS_INLINE inline __attribute__((always_inline))
#define ADD(x, y) ((x) + (y))
ALWAYS_INLINE int always_inline_add(int x, int y) {
return ADD(x, y);
}
int normal_add(int x, int y) {
return ADD(x, y);
}
아니면 그냥 이것을 가질 수도 있습니다.
#define ADD(x, y) ((x) + (y))
int add(int x, int y) {
return ADD(x, y);
}
int main() {
printf("%d\n", ADD(2,2)); // always inline
printf("%d\n", add(2,2)); // normal function call
return 0;
}
또한 함수의 인라인을 강제로 설정하면 코드 속도가 빨라지지 않을 수 있습니다.인라인 함수를 사용하면 더 큰 코드가 생성되어 더 많은 캐시 누락이 발생할 수 있습니다.그게 도움이 되길 바랍니다.
답은 당신의 기능, 당신이 무엇을 요청하는지, 그리고 당신의 기능의 성격에 달려있다는 것입니다.최선의 방법은 다음과 같습니다.
- 컴파일러에게 인라인을 원한다고 말합니다.
- 함수를 정적으로 만듭니다(일부 모드에서는 의미가 gcc로 약간 변경되므로 extern에 주의하십시오).
- 컴파일러 옵션을 설정하여 인라인을 원하는 옵티마이저에 알리며 인라인 한계를 적절하게 설정합니다.
- 컴파일러에서 인라인을 사용할 수 없는 경고 설정
- 출력을 확인합니다(생성된 어셈블리를 확인할 수 있음).
컴파일러 힌트
여기서의 답변은 인라인의 한 측면만을 다루고 있으며, 언어는 컴파일러에 힌트를 줍니다.표준이 다음과 같이 말할 때:
함수를 인라인 함수로 만드는 것은 함수 호출이 가능한 한 빠르다는 것을 의미합니다.이러한 제안이 효과적인 범위는 구현 정의된 것입니다.
이는 다음과 같은 다른 강력한 힌트의 경우일 수 있습니다.
- 의 GNU »
__attribute__((always_inline))
일반적으로 최적화를 지정하지 않으면 함수에 인라인이 적용되지 않습니다.인라인으로 선언된 함수의 경우 최적화 수준이 지정되지 않은 경우에도 이 속성은 함수를 인라인화합니다. - 마이크로소프트의
__forceinline
__force 인라인 키워드는 비용/편익 분석을 재정의하고 프로그래머의 판단에 의존합니다.__force 인라인을 사용할 때는 주의해야 합니다.__force 인라인을 무분별하게 사용하면 성능 향상 효과가 미미하거나 경우에 따라 성능 손실(예: 더 큰 실행 파일의 페이징 증가로 인해)이 발생할 수 있습니다.
이 두 가지 모두 가능한 인라인, 그리고 결정적으로 컴파일러 플래그에 의존합니다.인라인 함수를 사용하려면 컴파일러의 최적화 설정을 이해해야 합니다.
인라인을 사용하여 현재 사용 중인 컴파일 장치에 대한 기존 기능을 대체할 수도 있습니다.알고리즘에 대한 대략적인 답변이 충분할 때 또는 로컬 데이터 구조를 사용하여 더 빠른 방법으로 결과를 얻을 수 있을 때 사용할 수 있습니다.
인라인 정의는 외부 정의에 대한 대안을 제공하며, 변환기는 이를 사용하여 동일한 변환 단위에서 함수에 대한 호출을 구현할 수 있습니다.함수에 대한 호출이 인라인 정의를 사용하는지 외부 정의를 사용하는지 여부는 지정되지 않습니다.
일부 함수는 인라인화할 수 없습니다.
예를 들어 인라인화할 수 없는 GNU 컴파일러 함수는 다음과 같습니다.
함수 정의에서 특정 용도를 사용하면 인라인 대체에 적합하지 않을 수 있습니다.이러한 용도로는 변수 함수, 할당 사용, 변수 길이 데이터 유형 사용(변수 길이 참조), 계산된 goto 사용(값 레이블 참조), 비로컬 goto 사용 및 중첩 함수(내포 함수 참조)가 있습니다.-Winline 사용은 인라인으로 표시된 함수를 대체할 수 없는 경우 경고하고 실패의 원인을 제공합니다.
그래서 심지어always_inline
당신이 기대하는 것을 하지 않을 수도 있습니다.
컴파일러 옵션
C99의 인라인 힌트를 사용하는 것은 당신이 찾고 있는 인라인 동작을 컴파일러에 지시하는 것에 달려 있습니다.
예를 들어 GCC에는 다음이 있습니다.
-fno-inline
,-finline-small-functions
,-findirect-inlining
,-finline-functions
,-finline-functions-called-once
,-fearly-inlining
,-finline-limit=n
Microsoft 컴파일러에는 인라인의 효과를 지시하는 옵션도 있습니다.일부 컴파일러에서는 실행 중인 프로필을 고려하여 최적화할 수도 있습니다.
저는 프로그램 최적화의 더 넓은 맥락에서 인라인을 볼 가치가 있다고 생각합니다.
인라이닝 방지
당신은 특정 함수에 밑줄을 긋는 것을 원하지 않는다고 언급했습니다.이 작업은 다음과 같은 설정을 통해 수행될 수 있습니다.__attribute__((always_inline))
옵티마이저를 켜지 않아도 됩니다.그러나 최적화 도구가 필요할 수도 있습니다.여기서 한 가지 옵션은 원하지 않는다는 것을 암시하는 것입니다.__attribute__ ((noinline))
하지만 왜 이런 경우가 있을까요?
다른 형태의 최적화
루프를 재구성하고 분기를 방지하는 방법도 고려할 수 있습니다.분기 예측은 극적인 효과를 가져올 수 있습니다.이에 대한 흥미로운 토론은 다음을 참조하십시오.정렬된 배열을 처리하는 것이 정렬되지 않은 배열보다 빠른 이유는 무엇입니까?
그러면 내부 루프를 작게 만들어 풀어서 불변량을 확인할 수도 있습니다.
다을사용커소있습다니스가널음는을 하는 커널 #define
s는 동일한 본체로 여러 개의 서로 다른 명명된 함수를 정의하는 매우 흥미로운 방법입니다.이것은 유지해야 할 두 가지 다른 기능을 갖는 문제를 해결합니다.(어느 것인지 잊어버렸어요...)제 생각은 이와 같은 원칙에 기초하고 있습니다.
정의를 사용하는 방법은 필요한 컴파일 장치에 인라인 함수를 정의하는 것입니다.방법을 시연하기 위해 간단한 기능을 사용합니다.
int add(int a, int b);
합니다. 발생기를 .#define
헤더 파일에서 함수의 일반 버전(인라인되지 않은 버전)의 함수 프로토타입을 선언합니다.
그런 다음 두 개의 개별 함수 생성기를 선언합니다. 하나는 일반 함수용이고 다른 하나는 인라인 함수용입니다.선언하는 인라인 함수static __inline__
파일 중 하나에서 인라인 함수를 호출해야 하는 경우 생성기 정의를 사용하여 소스를 가져옵니다.일반 기능을 사용하는 데 필요한 다른 모든 파일에서는 프로토타입에 헤더를 포함하기만 하면 됩니다.
코드 테스트 대상:
Intel(R) Core(TM) i5-3330 CPU @ 3.00GHz
Kernel Version: 3.16.0-49-generic
GCC 4.8.4
코드는 천 단어 이상의 가치가 있습니다. 따라서:
파일 계층
+
| Makefile
| add.h
| add.c
| loop.c
| loop2.c
| loop3.c
| loops.h
| main.c
덧셈
#define GENERATE_ADD(type, prefix) \
type int prefix##add(int a, int b) { return a + b; }
#define DEFINE_ADD() GENERATE_ADD(,)
#define DEFINE_INLINE_ADD() GENERATE_ADD(static __inline__, inline_)
int add(int, int);
이것은 보기에는 좋지 않지만, 두 가지 다른 기능을 유지하는 작업을 줄입니다. 함수는 수는다같정완다니의됩전히이음과에 .GENERATE_ADD(type,prefix)
매크로, 그래서 기능을 변경해야 할 경우 이 매크로를 변경하면 다른 모든 것이 변경됩니다.
다음 분.DEFINE_ADD()
에서 다니됩출에서 부를 입니다.add.c
의 의일버생다니성을 합니다.add
.DEFINE_INLINE_ADD()
라하 는기액수있다습니세할스능에라는 수 .inline_add
당신의 일반적인 서명과 동일한 서명이 있습니다.add
함수이지만 이름(inline_ 접두사)이 다릅니다.
참고: 사용하지 않았습니다.__attribute((always_inline))__
를 할 때-O3
- 래그플 - 더__inline__
그 일을 했습니다.하지만, 만약 당신이 사용하고 싶지 않다면.-O3
매개 변수:
#define DEFINE_INLINE_ADD() GENERATE_ADD(static __inline__ __attribute__((always_inline)), inline_)
부가적인
#include "add.h"
DEFINE_ADD()
로 간단한 DEFINE_ADD()
매크로 발생기이렇게 하면 함수의 일반 버전(인라인이 표시되지 않는 버전)이 선언됩니다.
루프.c.
#include <stdio.h>
#include "add.h"
DEFINE_INLINE_ADD()
int loop(void)
{
register int i;
for (i = 0; i < 100000; i++)
printf("%d\n", inline_add(i + 1, i + 2));
return 0;
}
여서기에서.loop.c
로의전를볼다니있습수로 하는 것을 볼 수 .DEFINE_INLINE_ADD()
이 기능을 사용하면 이 기능에 액세스할 수 있습니다.inline_add
기능. 할 컴할때모두일파모▁all두때,할▁when.inline_add
함수가 인라인으로 표시됩니다.
루프2.c
#include <stdio.h>
#include "add.h"
int loop2(void)
{
register int i;
for (i = 0; i < 100000; i++)
printf("%d\n", add(i + 1, i + 2));
return 0;
}
의 의사수용버할있보것위입다니한여기주음을전을을 사용할 수 있다는 것을 위한 것입니다.add
일반적으로 다른 파일에서.
루프 3.c
#include <stdio.h>
#include "add.h"
DEFINE_INLINE_ADD()
int loop3(void)
{
register int i;
printf ("add: %d\n", add(2,3));
printf ("add: %d\n", add(4,5));
for (i = 0; i < 100000; i++)
printf("%d\n", inline_add(i + 1, i + 2));
return 0;
}
이는 동일한 컴파일 장치에서 두 기능을 모두 사용할 수 있지만 한 기능은 인라인 방식으로, 다른 기능은 인라인 방식으로 사용할 수 없음을 보여줍니다(자세한 내용은 아래의 GDB 분해 참조).
루프.h.
/* prototypes for main */
int loop (void);
int loop2 (void);
int loop3 (void);
주.c.
#include <stdio.h>
#include <stdlib.h>
#include "add.h"
#include "loops.h"
int main(void)
{
printf("%d\n", add(1,2));
printf("%d\n", add(2,3));
loop();
loop2();
loop3();
return 0;
}
파일 만들기
CC=gcc
CFLAGS=-Wall -pedantic --std=c11
main: add.o loop.o loop2.o loop3.o main.o
${CC} -o $@ $^ ${CFLAGS}
add.o: add.c
${CC} -c $^ ${CFLAGS}
loop.o: loop.c
${CC} -c $^ -O3 ${CFLAGS}
loop2.o: loop2.c
${CC} -c $^ ${CFLAGS}
loop3.o: loop3.c
${CC} -c $^ -O3 ${CFLAGS}
를 사용하는 .__attribute__((always_inline))
▁the다를 변경할 수 .Makefile
대상:
CC=gcc
CFLAGS=-Wall -pedantic --std=c11
main: add.o loop.o loop2.o loop3.o main.o
${CC} -o $@ $^ ${CFLAGS}
%.o: %.c
${CC} -c $^ ${CFLAGS}
컴파일
$ make
gcc -c add.c -Wall -pedantic --std=c11
gcc -c loop.c -O3 -Wall -pedantic --std=c11
gcc -c loop2.c -Wall -pedantic --std=c11
gcc -c loop3.c -O3 -Wall -pedantic --std=c11
gcc -Wall -pedantic --std=c11 -c -o main.o main.c
gcc -o main add.o loop.o loop2.o loop3.o main.o -Wall -pedantic --std=c11
분해
$ gdb main
(gdb) disass add
0x000000000040059d <+0>: push %rbp
0x000000000040059e <+1>: mov %rsp,%rbp
0x00000000004005a1 <+4>: mov %edi,-0x4(%rbp)
0x00000000004005a4 <+7>: mov %esi,-0x8(%rbp)
0x00000000004005a7 <+10>:mov -0x8(%rbp),%eax
0x00000000004005aa <+13>:mov -0x4(%rbp),%edx
0x00000000004005ad <+16>:add %edx,%eax
0x00000000004005af <+18>:pop %rbp
0x00000000004005b0 <+19>:retq
(gdb) disass loop
0x00000000004005c0 <+0>: push %rbx
0x00000000004005c1 <+1>: mov $0x3,%ebx
0x00000000004005c6 <+6>: nopw %cs:0x0(%rax,%rax,1)
0x00000000004005d0 <+16>:mov %ebx,%edx
0x00000000004005d2 <+18>:xor %eax,%eax
0x00000000004005d4 <+20>:mov $0x40079d,%esi
0x00000000004005d9 <+25>:mov $0x1,%edi
0x00000000004005de <+30>:add $0x2,%ebx
0x00000000004005e1 <+33>:callq 0x4004a0 <__printf_chk@plt>
0x00000000004005e6 <+38>:cmp $0x30d43,%ebx
0x00000000004005ec <+44>:jne 0x4005d0 <loop+16>
0x00000000004005ee <+46>:xor %eax,%eax
0x00000000004005f0 <+48>:pop %rbx
0x00000000004005f1 <+49>:retq
(gdb) disass loop2
0x00000000004005f2 <+0>: push %rbp
0x00000000004005f3 <+1>: mov %rsp,%rbp
0x00000000004005f6 <+4>: push %rbx
0x00000000004005f7 <+5>: sub $0x8,%rsp
0x00000000004005fb <+9>: mov $0x0,%ebx
0x0000000000400600 <+14>:jmp 0x400625 <loop2+51>
0x0000000000400602 <+16>:lea 0x2(%rbx),%edx
0x0000000000400605 <+19>:lea 0x1(%rbx),%eax
0x0000000000400608 <+22>:mov %edx,%esi
0x000000000040060a <+24>:mov %eax,%edi
0x000000000040060c <+26>:callq 0x40059d <add>
0x0000000000400611 <+31>:mov %eax,%esi
0x0000000000400613 <+33>:mov $0x400794,%edi
0x0000000000400618 <+38>:mov $0x0,%eax
0x000000000040061d <+43>:callq 0x400470 <printf@plt>
0x0000000000400622 <+48>:add $0x1,%ebx
0x0000000000400625 <+51>:cmp $0x1869f,%ebx
0x000000000040062b <+57>:jle 0x400602 <loop2+16>
0x000000000040062d <+59>:mov $0x0,%eax
0x0000000000400632 <+64>:add $0x8,%rsp
0x0000000000400636 <+68>:pop %rbx
0x0000000000400637 <+69>:pop %rbp
0x0000000000400638 <+70>:retq
(gdb) disass loop3
0x0000000000400640 <+0>: push %rbx
0x0000000000400641 <+1>: mov $0x3,%esi
0x0000000000400646 <+6>: mov $0x2,%edi
0x000000000040064b <+11>:mov $0x3,%ebx
0x0000000000400650 <+16>:callq 0x40059d <add>
0x0000000000400655 <+21>:mov $0x400798,%esi
0x000000000040065a <+26>:mov %eax,%edx
0x000000000040065c <+28>:mov $0x1,%edi
0x0000000000400661 <+33>:xor %eax,%eax
0x0000000000400663 <+35>:callq 0x4004a0 <__printf_chk@plt>
0x0000000000400668 <+40>:mov $0x5,%esi
0x000000000040066d <+45>:mov $0x4,%edi
0x0000000000400672 <+50>:callq 0x40059d <add>
0x0000000000400677 <+55>:mov $0x400798,%esi
0x000000000040067c <+60>:mov %eax,%edx
0x000000000040067e <+62>:mov $0x1,%edi
0x0000000000400683 <+67>:xor %eax,%eax
0x0000000000400685 <+69>:callq 0x4004a0 <__printf_chk@plt>
0x000000000040068a <+74>:nopw 0x0(%rax,%rax,1)
0x0000000000400690 <+80>:mov %ebx,%edx
0x0000000000400692 <+82>:xor %eax,%eax
0x0000000000400694 <+84>:mov $0x40079d,%esi
0x0000000000400699 <+89>:mov $0x1,%edi
0x000000000040069e <+94>:add $0x2,%ebx
0x00000000004006a1 <+97>:callq 0x4004a0 <__printf_chk@plt>
0x00000000004006a6 <+102>:cmp $0x30d43,%ebx
0x00000000004006ac <+108>:jne 0x400690 <loop3+80>
0x00000000004006ae <+110>:xor %eax,%eax
0x00000000004006b0 <+112>:pop %rbx
0x00000000004006b1 <+113>:retq
기호 테이블
$ objdump -t main | grep add
0000000000000000 l df *ABS* 0000000000000000 add.c
000000000040059d g F .text 0000000000000014 add
$ objdump -t main | grep loop
0000000000000000 l df *ABS* 0000000000000000 loop.c
0000000000000000 l df *ABS* 0000000000000000 loop2.c
0000000000000000 l df *ABS* 0000000000000000 loop3.c
00000000004005c0 g F .text 0000000000000032 loop
00000000004005f2 g F .text 0000000000000047 loop2
0000000000400640 g F .text 0000000000000072 loop3
$ objdump -t main | grep main
main: file format elf64-x86-64
0000000000000000 l df *ABS* 0000000000000000 main.c
0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.5
00000000004006b2 g F .text 000000000000005a main
$ objdump -t main | grep inline
$
음, 바로 그겁니다.3시간 동안 키보드로 머리를 쾅쾅 치면서 그것을 알아내려고 노력한 결과, 이것이 제가 생각할 수 있는 최선이었습니다.잘못이 있으면 언제든지 지적해 주시면 정말 감사하겠습니다.저는 이 특별한 인라인 원 함수 호출에 정말 관심이 생겼습니다.
동일한 함수에 대해 두 개의 이름을 지정하는 것이 괜찮다면 always_inline 특성이 모든 호출에 영향을 미치지 않도록 "차단"하기 위해 함수 주위에 작은 래퍼를 만들 수 있습니다. 제예서는에,,loop_inlined
성능이 중요한 섹션에서 사용하는 이름인 반면 일반 섹션에서는loop
다른 모든 곳에서 사용될 것입니다.
인라인.h
#include <stdlib.h>
static inline int loop_inlined() __attribute__((always_inline));
int loop();
static inline int loop_inlined() {
int n = 0, i;
for(i = 0; i < 10000; i++)
n += rand();
return n;
}
inline.c
#include "inline.h"
int loop() {
return loop_inlined();
}
주.c.
#include "inline.h"
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("%d\n", loop_inlined());
printf("%d\n", loop());
return 0;
}
이는 최적화 수준에 관계없이 작동합니다.를사여컴일파로 gcc inline.c main.c
Intel에서 제공하는 기능:
4011e6: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp)
4011ed: 00
4011ee: eb 0e jmp 4011fe <_main+0x2e>
4011f0: e8 5b 00 00 00 call 401250 <_rand>
4011f5: 01 44 24 1c add %eax,0x1c(%esp)
4011f9: 83 44 24 18 01 addl $0x1,0x18(%esp)
4011fe: 81 7c 24 18 0f 27 00 cmpl $0x270f,0x18(%esp)
401205: 00
401206: 7e e8 jle 4011f0 <_main+0x20>
401208: 8b 44 24 1c mov 0x1c(%esp),%eax
40120c: 89 44 24 04 mov %eax,0x4(%esp)
401210: c7 04 24 60 30 40 00 movl $0x403060,(%esp)
401217: e8 2c 00 00 00 call 401248 <_printf>
40121c: e8 7f ff ff ff call 4011a0 <_loop>
401221: 89 44 24 04 mov %eax,0x4(%esp)
401225: c7 04 24 60 30 40 00 movl $0x403060,(%esp)
40122c: e8 17 00 00 00 call 401248 <_printf>
처음 7개의 지시사항은 인라인 통화이고, 일반 통화는 5개의 지시사항 이후에 발생합니다.
코드 본문을 별도의 헤더 파일에 작성할 것을 제안합니다.헤더 파일을 다른 호출을 위해 C 파일의 본문에 인라인으로 포함합니다.
void demo(void)
{
#include myBody.h
}
importantloop
{
// code
#include myBody.h
// code
}
당신이 인라인을 하고 싶으니 당신의 기능은 작은 것이라고 생각합니다, 그렇다면 summary로 작성해 보는 것은 어떨까요?
함수에 대한 특정 호출만 인라인화하는 것에 대해서는 이 작업을 수행할 수 있는 방법이 없다고 생각합니다.함수가 인라인으로 선언되고 컴파일러가 인라인으로 지정하면 해당 함수에 대한 호출이 표시되는 모든 곳에서 이를 수행합니다.
언급URL : https://stackoverflow.com/questions/14571593/how-can-i-inline-a-particular-function-call
'source' 카테고리의 다른 글
Git Clone: 파일만 부탁합니다. (0) | 2023.08.24 |
---|---|
PowerShell을 사용하여 월 번호를 월 이름으로 변환 (0) | 2023.08.24 |
판다 및 매트플로트립을 사용하여 범주형 데이터 표시 (0) | 2023.08.24 |
oracle: from 절에 별칭을 할당할 수 있습니까? (0) | 2023.08.24 |
Javascript에서 사전 이해 또는 객체 'map' (0) | 2023.08.24 |