【问题标题】:Return a structure with const array in C在 C 中返回具有 const 数组的结构
【发布时间】:2015-05-12 15:33:50
【问题描述】:

在 C 中返回带有数组数据成员的结构是否安全? 类似的东西

struct my_str {
 int v[5];
};

struct my_str ret_stupid() {
 struct my_str rval;

 /*do something..*/

 return rval;
}

我不知道为什么...我有点困惑。 (我已经尝试过了,它确实有效)。是否有一些标准来解释此操作实际上是如何执行的?我的意思是结构返回和赋值的机制也有助于更好地理解。

【问题讨论】:

  • my_str 包含 5 个ints,当你返回结构体时会被复制。
  • @Javia1492 您链接的问题不是这个问题;是什么让你相信它是?
  • @Lukkio 它的工作方式取决于实现,但您应该期望结构被返回它的函数复制到堆栈中,然后调用者将其副本从堆栈中取出。如果您的调用者没有返回结构的函数的有效原型,您会期望结果损坏(但无论是否损坏,这将是未定义的行为)。

标签: c arrays


【解决方案1】:

在 C 中返回带有数组数据成员的结构是否安全?

是的。

struct 按位复制。按位复制具有数组成员的struct 可确保struct 的副本也具有该数组的副本。

【讨论】:

    【解决方案2】:

    结构很像数组。 它们可以包含任何类型的变量。 只要您不留空隙或调用预处理器指令#pragma pack,它们的地址就会被堆叠排序。


    “是否安全”,取决于隐藏在那里的代码..

    /做点什么../

    但总的来说 - 是的。这只是struct my_str 类型的函数,必须返回struct my_str


    结构包含什么 - 无关紧要。仍然可以安全使用。

    【讨论】:

      【解决方案3】:

      您可以毫无问题地从函数返回结构。它是语言中定义明确的部分。您也可以将结构传递给函数 - 用于参数传递、返回值和赋值的结构与任何内置类型完全相同。

      这是一个例子

      #include <stdio.h>
      
      int func(int x) 
      {
       int r = x;
       return r;
      }
      
      int main(void)
      {
       int x = 12;
       int y = func(x);
       printf("%d\n", y);
       return 0;
      }
      

      【讨论】:

        【解决方案4】:

        如果不是数组成员,则返回值将是“右值”,该值只是您在 return 表达式中的值的副本。如果你有

        struct toto {
          double a;
        };
        
        struct toto g(void) {
           struct toto retval = { 0.0 };
           ...
           return retval;
        }
        
        int main(void) {
           printf("%g\n", g().a);
        }
        

        printf 调用的参数看到了函数内部使用的变量retval 的副本。 g().a 调用函数并使用返回 value.a 字段。

        这个返回值是和 不是对象但仅因其“价值”而存在的实体,在 C 术语中称为右值。它只能在分配的 RHS 上找到,因此“rvalue”中的“r”。

        您给出的情况实际上是经过特殊处理的,因为“值”不足以满足数组的所有用例。所以这会生成一个所谓的“具有临时生命周期的对象”。这是必需的,因为如果您要执行ret_stupid().v[2][] 运算符希望有一个指针,而指针只能指向一个对象,而不是一个值。

        这些对象仅“存在”在包含函数调用的表达式中,即使它们不是 const 限定的,您也不允许修改它们。 p>

        总而言之,这是 C 的一个极端情况,你不应该滥用它。

        【讨论】:

        • 我不明白你所说的特殊待遇……你能说得具体一点吗?
        • 为了清楚起见...我不明白写ret_stupid().v[2]...这是什么意思?此外,我提出的结构返回与返回的静态数组有什么区别,我知道我不能这样做......
        • @Lukkio,请看我的编辑,希望现在更清楚。
        猜你喜欢
        • 1970-01-01
        • 2020-12-01
        • 2014-06-02
        • 1970-01-01
        • 2020-03-23
        • 1970-01-01
        • 2023-03-09
        • 2021-07-27
        • 1970-01-01
        相关资源
        最近更新 更多