use*_*348 6 c standards-compliance
请考虑以下代码:
char buffer[256];
struct stX
{
int a;
int b;
int c;
};
void * my_memcpy ( void * destination, const void * source, size_t num );
int main()
{
struct stX x;
x.a = 1;
x.b = 2;
x.c = 3;
my_memcpy(buffer, &x.b, 2 * sizeof(int));
{
int i;
for (i = 0; i < 2 * sizeof(int); ++i) {
printf("%d\n", buffer[i]);
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
嵌入式系统的特定编译器决定删除对xa和xc的赋值(因为它们从未使用过(至少不是很明显)).这是c标准允许的优化吗?
当然,在包含的赋值中将结构实例定义为volatile.
gcc和msvc不执行此优化(但这不是一个真正的推理).
更新:正如一些答案(正确)假设的那样,编译器可以根据已知的memcpy定义进行优化,但是,这不是我的特定实现所做的.(它保留了堆栈结构的内存,只是不执行赋值.)假设我们用一个编译器没有定义的函数替换了memcpy.另外,假设在函数调用之后使用缓冲区.我相应地更新了上面的示例代码.
是的,只要应用程序的可观察行为不改变,编译器就可以自由地执行任何操作。*
但这假设您有一个符合要求的程序,即具有明确定义的行为的程序。您的代码没有表现出明确定义的行为;x.c通过取消引用指针来访问是无效的x.b(这是您隐式要求memcpy做的)。
更新:以上段落可能不正确;请参阅评论中的讨论...
访问易失性对象、修改对象、修改文件或调用执行任何这些操作的函数都是副作用,即执行环境状态的变化。
...
如果实际的实现可以推断出其值未被使用并且不会产生所需的副作用,则不需要计算表达式的一部分