我有以下C代码,它在没有优化(-O0)的情况下工作得很好,但在使用-Os时有意外的行为:
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
static bool functionA(uint8_t* ptr1)
{
for (int i = 0; i < 16; i++)
{
ptr1[i] = i;
}
printf("functionA\n");
return true;
}
static bool functionB(uint8_t* ptr1)
{
bool retVal = false;
uint8_t ptr2[16] = {0};
if (functionA(ptr2))
{
retVal = true;
memcpy(ptr1, ptr2, 16);
}
return retVal;
}
int main(void)
{
const uint8_t* p = NULL;
const uint8_t BUF[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
for (int i = 1; i <= 2; i++)
{
if (i == 1)
{
uint8_t buff32[32] = {0x5};
if (functionB(buff32))
{
p = buff32;
break;
}
continue;
}
else
{
p = BUF;
}
}
for(int i = 0; i < 16; i++)
{
printf("%x ", p[i]);
}
printf("\n");
return 0;
}
在使用"-O0"编译代码时,我得到的结果是:
functionA
0 1 2 3 4 5 6 7 8 9 a b c d e f
但是,使用"-Os"或"-03"(而不是"-O2"):
functionA
16 24 97 6b fc 7f 0 0 8d f2 b7 c ed 55 0 0
我用不同的编译器(如ARM GCC 10.3.1)在Godbolt上试了一下,我发现"函数B"中的Memcpy的代码没有编译.在main
开头改变buff32
的范围似乎就解决了这个问题.看起来GCC判断缓冲区在其作用域内不再使用,认为它未使用,因此对其进行了优化.
有没有可能从编译器那里得到警告? 这是一种未定义的行为吗?