【问题标题】:why return value of function can be assigned to?为什么函数的返回值可以赋值给?
【发布时间】:2011-08-02 09:33:41
【问题描述】:

考虑以下函数:

 char *f()
 {   
 char *s=malloc(8);
 }
 main()
 {
  printf("%c",*f()='A');
 }

如果我注释 char *s=malloc(8); 行,我会收到一个错误,好像赋值 *f()='A' 访问了无效内存。既然我从不返回任何变量,为什么上面的赋值完全有效?

第二个问题:'A' 分配给函数返回时创建的临时变量。那么为什么++a等不能​​作为左值呢?

【问题讨论】:

  • 您使用的是哪个编译器?请发布确切的错误消息。
  • 编译这段代码时没有任何警告吗?例如,在 f 中没有返回?
  • 仅仅因为你观察到某些东西在工作并不意味着它完全有效。 int min(int a, int b) { return a; } 这个函数的工作时间平均为 50%。
  • “为什么 [它] 会起作用?”因为您的编译器的警告不够高和/或您非常不走运。
  • 我使用代码块。我知道这是错误的代码。没有警告。所以你的意思是在没有返回语句的情况下,函数返回一个随机地址。第二个问题呢?

标签: c function return-value lvalue


【解决方案1】:

假设返回值在寄存器中传递,当从 f() 返回时,malloc 的返回值可能仍然存在。纯属偶然。

当分配给*f() 时,您不是分配给临时的,而是分配给从 malloc 返回的内存。分配给 ++a 完全不同。

【讨论】:

  • 虽然我想念这里的关键短语 - 未定义的行为。
  • 问题是为什么它似乎有效。如果是正确的,则不是。
  • 我认为问题在于何时以及为什么可以分配给左值。
【解决方案2】:

您的函数f() 没有返回任何内容,您需要添加:

return s;

但是,老实说,这只是你问题的开始。你还需要free()f()的返回值。

我不知道你为什么把这个问题标记为 C++,这显然是 C,所以我没有这样标记。

【讨论】:

  • 问题是,“X 代码错误但似乎工作正常,为什么?”而你的回答是,“X 代码是错误的 - 你需要使用 Y 代码。”
  • @Chris Lutz,啊……抱歉。当我看到代码时,我陷入了感染性休克,这让我的判断蒙上了阴影。
  • 我去过那里。当我看到 void main() 时,我开始看到红色
【解决方案3】:

你必须用return语句返回f()中的指针,否则会返回非法指针:

char *f()
{   
    char *s=malloc(8);
    return s;
}

【讨论】:

  • "...否则会返回非法指针"这到底是从哪里来的?
  • 可能是因为我外语使用不当。但那句话到底有什么问题呢?
  • 根据标准(表示未定义的行为)或在这个现实世界的示例中(来自malloc 的指针留在返回寄存器中,实际上导致它是也从f 返回)。
【解决方案4】:

您的函数不返回任何内容。由于您使用返回类型 char * 声明函数,因此不返回任何内容会导致未定义的行为,如当前 C++ 标准的第 6.6.3.2 段中所定义:

从函数的末尾流出等同于return 没有 价值;这会导致值返回中的未定义行为 功能。

未定义的行为意味着anything can happen。要解决该问题,您的函数应如下所示:

char *f()
{   
    return malloc(8);
}

【讨论】:

    【解决方案5】:

    在您的函数中,您返回一个可以分配内容的指针...++a 通过返回 const 引用或实例来阻止它。如果你有const char* f() { ... },你可以有同样的行为。

    当然你也可以用不同的方式实现++a :)

    【讨论】:

      【解决方案6】:

      1/ f()的返回是一个未初始化的指针,但存在。
      *f() 返回未指定(随机)地址所指向的值。
      在此地址写入是无效的内存访问,或者如果此地址“偶然”是一块可写的内存(堆栈或先前分配的堆),则可能不是。
      在 C 中,您有责任确保正确访问内存。

      2/ 'A' 在这里没有分配给一个临时的。

      【讨论】:

        猜你喜欢
        • 2011-06-19
        • 1970-01-01
        • 2017-04-18
        • 2020-08-26
        • 1970-01-01
        • 2018-05-08
        • 2012-06-16
        • 2020-09-21
        • 2022-12-04
        相关资源
        最近更新 更多