普通老C:访问返回struct的函数的成员

时间:2016-01-29 09:23:02

标签: c

请你帮我解决一下合法性问题"。

假设foo()是一个返回结构的函数,将结构的成员直接赋值给变量是否正式可接受,例如

x = foo().member

GNU-C编译器和嵌入式C编译器(Keil)都接受了这一点而没有任何抱怨,但这根据官方C标准实际上是合法的还是只是这些特定编译器的放松态度?如果它是合法的,它一直是合法的还是最近的发展?

这是一个编译并运行OK的例子:

typedef struct
{
    int a;
    int b;
} footype;

footype testfoo(void)
{
    footype n;

    n.a = 1;
    n.b = 2;
    return n;
}

int main()
{
    printf("\nTest = %d\n", testfoo().a);
    return 0;
}

4 个答案:

答案 0 :(得分:1)

是的,这是标准的C语法。

答案 1 :(得分:1)

testfoo函数返回结构的临时实例。此示例可以在示例中显示,并且临时实例有效,直到完整表达式(即您的案例中的printf调用)完成。

相当于

{
    footype temp = testfoo();
    printf("\nTest = %d\n", temp.a);
}

答案 2 :(得分:0)

这是表达评估结果的标准案例 流程:

testfoo().a

是标准C表达式,其中:

  1. testfoo()结果,函数返回的结果是我们的结构footype
  2. 然后编译器将运算符.应用于此结构。
  3. 点运算符访问字段a并创建新结果。
  4. 最终表达式结果用于printf()。 这始终有效 即:

    int *bar(void); //bar is afunnction that returns an int pointer ... i = bar()[10]; //We access the 10th element pointed by bar()

答案 3 :(得分:0)

出于兴趣,我编译了您的示例并查看了生成的程序集。首先,每个编译器都可以以自己的方式解决这个问题。我用VC2008。

在您的示例中,编译器在其寄存器中返回结构。

我将结构更改为包含一个大字符串,因此编译器将耗尽寄存器。它现在改变了函数的签名以接收指针,并在堆栈(调用者的堆栈帧)上分配了结构的实例,然后使用指向此结构的指针调用该函数。该函数使用此指针将结果复制到堆栈上的结构。