我有以下的C代码(我删去了其他一些调用和检查):
#include <stdint.h>
#include <memory.h>
extern char buffer[];
extern void getstr1(char *buff, int buflen);
extern void getstr2(char **s);
extern void dosomething(char *s);
void myfn()
{
char *s, *s1;
int len;
getstr1(buffer, 128);
getstr2(&s);
len = *s + *buffer;
memcpy(buffer + *buffer + 1, s + 1, (*s) * sizeof(char));
*buffer = len;
dosomething(buffer);
}
使用/O2优化选项的MSVC将产生以下输出:
_s$ = -4 ; size = 4
void myfn(void) PROC ; myfn, COMDAT
push ecx
push 128 ; 00000080H
push OFFSET char * buffer ; buffer
call void getstr1(char *,int) ; getstr1
lea eax, DWORD PTR _s$[esp+12]
push eax
call void getstr2(char * *) ; getstr2
mov eax, DWORD PTR _s$[esp+16]
push OFFSET char * buffer ; buffer
mov al, BYTE PTR [eax]
add BYTE PTR char * buffer, al
call void dosomething(char *) ; dosomething
add esp, 20 ; 00000014H
ret 0
void myfn(void) ENDP ; myfn
您可以在Godbolt上检查这个:https://godbolt.org/z/m9yH0C
为什么编译器省略了memcpy调用?有趣的是,将外部变量声明为“extern char buffer[N];”(其中N >= 2)或“extern char *buffer;”会使编译器使用memcpy。同时,将memcpy替换为memmove也会产生同样的效果。我知道当源区域与目标区域重叠时可能会出现未定义行为,但在这里编译器并不知道这一点。
extern char buffer[];
合法吗? - NathanOliversizeof buffer
都没有太多意义。 - Jabberwockyextern char buffer[];
是合法的。此外,它与extern char *buffer;
完全不同。 - Antti Haapala -- Слава Україні