Я не смог найти много документации о том, в каком сценарии ios происходит, так что кто-то скажет мне?
Не могли бы вы привести пример кода?
Передача функции в качестве указателя на функцию и вызов ее из другой единицы перевода (даже из той же единицы перевода, предполагая, что оптимизация равна -O0 или -Os, и она лучше подходит для размера или, как на самом деле просто .. . "lucky") будет эффективно запрещать возможность встраивания функции:
cat << EOF > main.c
__attribute__((__always_inline__))
static inline
void f(void) {
printf("Hey buddy!\n");
}
extern void call_fp(void (*fp)(void));
int main() {
call_fp(f);
}
EOF
cat << EOF > g.c
void call_fp(void (*fp)(void)) {
printf("Hey pal!");
fp();
}
EOF
Компилировать и проверять:
$ gcc -g -Ofast main.c g.c && objdump -S ./a.out | grep '<main>:\|<call_fp>:'
0000000000001050 <main>:
int main() {
1050: 48 83 ec 08 sub $0x8,%rsp
call_fp(f);
1054: 48 8d 3d 35 01 00 00 lea 0x135(%rip),%rdi # 1190 <f>
################################### vvvvv NOT INLINED ###############
105b: e8 40 01 00 00 callq 11a0 <call_fp>
}
1060: 31 c0 xor %eax,%eax
1062: 48 83 c4 08 add $0x8,%rsp
1066: c3 retq
1067: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
106e: 00 00
--
00000000000011a0 <call_fp>:
void call_fp(void (*fp)(void)) {
11a0: 53 push %rbx
printf("Hey pal!");
11a1: 31 c0 xor %eax,%eax
void call_fp(void (*fp)(void)) {
11a3: 48 89 fb mov %rdi,%rbx
printf("Hey pal!");
11a6: 48 8d 3d 62 0e 00 00 lea 0xe62(%rip),%rdi # 200f <_IO_stdin_used+0xf>
11ad: e8 8e fe ff ff callq 1040 <printf@plt>
fp();
11b2: 48 89 d8 mov %rbx,%rax
}
11b5: 5b pop %rbx
fp();
################################### vvvv NOT INLINED ####################
11b6: ff e0 jmpq *%rax
11b8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
11bf: 00
Вы все еще можете оптимизировать для единиц перевода с помощью LTO:
$ gcc -g -flto -Ofast main.c g.c && objdump -S ./a.out | grep '<main>:' -A30
int main() {
1050: 48 83 ec 08 sub $0x8,%rsp
void call_fp(void (*fp)(void)) {
printf("Hey pal!");
1054: 48 8d 3d a9 0f 00 00 lea 0xfa9(%rip),%rdi # 2004 <_IO_stdin_used+0x4>
105b: 31 c0 xor %eax,%eax
105d: e8 de ff ff ff callq 1040 <printf@plt>
printf("Hey buddy!\n");
1062: 48 8d 3d a4 0f 00 00 lea 0xfa4(%rip),%rdi # 200d <_IO_stdin_used+0xd>
####################### Both call_fp() and f() were inlined!!!!!!!!!!!!!
1069: e8 c2 ff ff ff callq 1030 <puts@plt>
call_fp(f);
}
106e: 31 c0 xor %eax,%eax
1070: 48 83 c4 08 add $0x8,%rsp
1074: c3 retq
1075: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
107c: 00 00 00
107f: 90 nop
Что касается __attribute__((__noinline__))
, я не встречал возможного случая, когда g cc предпочел бы встроить функцию __noinline__
.