C/C ++不定值:编译器优化提供不同的输出(示例) [英] C/C++ Indeterminate Values: Compiler optimization gives different output (example)

查看:107
本文介绍了C/C ++不定值:编译器优化提供不同的输出(示例)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎C/C ++编译器(clang,gcc等)会产生与优化级别有关的不同输出.您也可以检查此文章中包含的在线链接.

It seems like the C/C++ compiler (clang, gcc, etc) produces different output related to the optimization level. You may as well check the online link included in this post.

http://cpp.sh/5vrmv (将输出从无更改为-O3以查看差异)

http://cpp.sh/5vrmv (change output from none to -O3 to see the differences).

基于以下代码,有人可以解释我的几个问题:

Based on the following piece of code, could someone explain a few questions I have:

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    int *p = (int *)malloc(sizeof(int));
    free(p);
    int *q = (int *)malloc(sizeof(int));
    if (p == q) {
        *p = 10;
        *q = 14;
        printf("%d", *p);
    }
    return 0;
}

  1. 确定执行将始终进入if语句吗?我们如何知道两个指针p和q的地址相同?
  2. 为什么没有优化的输出为 14 ,而-O3的输出为相同的指令 10 ?
  1. Is it certain that the execution will always get into the if statement? How do we know the addresses of the two pointers, p and q, will be the same?
  2. Why does no-optimization has output 14, while -O3 has output 10 for the same instructions?

推荐答案

free(p);

这会将p的内容转换为无效的指针值.

This turns the contents of p into an invalid pointer value.

int *q = (int *)malloc(sizeof(int));

此行与p不相关.

if (p == q) {

这是实现定义的行为,因为p具有无效的指针值.

This is implementation-defined behaviour because p has an invalid pointer value.

    *p = 10;

最后,由于与上述相同的原因,这是未定义的行为.

And finally, this is undefined behaviour, for the same reason as above.

C ++标准§3.7.4.2/4:

C++ standard §3.7.4.2/4:

如果在标准中将参数赋给释放函数 库是一个不是空指针值(4.10)的指针, 释放功能应取消分配由 指针,呈现无效的所有指向该指针任何部分的指针 释放的存储.通过无效的指针值进行间接 将无效的指针值传递给释放函数 未定义的行为.任何其他使用无效指针值的操作都有 实施定义的行为.

If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer value (4.10), the deallocation function shall deallocate the storage referenced by the pointer, rendering invalid all pointers referring to any part of the deallocated storage. Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior.

因此,您的问题的答案是:

Therefore, the answers to your questions are:

确定执行总是会进入if语句吗?

Is it certain that the execution will always get into the if statement?

这取决于实现方式. C ++语言不能保证它.

It depends on the implementation. The C++ language does not guarantee it.

为什么没有优化的输出为14,而-O3的输出为相同的指令,则为10?

Why does no-optimization has output 14, while -O3 has output 10 for the same instructions?

因为当取消引用无效的指针时,行为是不确定的.

Because the behaviour is undefined when you dereference an invalid pointer.

在C中,比较本身是未定义的行为. C标准的附录J.2列出了行为未定义的情况,该列表包括:

In C, the comparison itself is undefined behaviour. Appendix J.2 in the C standard lists the circumstances in which the behaviour is undefined, and that list includes:

使用指向其生命周期已结束的对象的指针的值.

The value of a pointer to an object whose lifetime has ended is used.

您可能会发现以下问题,包括所有有趣的评论和答案:未定义,未指定和实现定义的行为

You may find the following question including all comments and answers interesting: Undefined, unspecified and implementation-defined behavior

这篇关于C/C ++不定值:编译器优化提供不同的输出(示例)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆