【问题标题】:What does this statement mean?这个声明是什么意思?
【发布时间】:2014-09-20 22:38:50
【问题描述】:

我不明白这个说法:f().array;... 是函数调用吗?还是访问类的属性? 语句data f(); 是构造函数的调用?对吗?

#include <iostream>
using namespace std;

void f()
{
    cout << "hello!" << endl;
}

struct data 
{ 
    int array[10]; 
};

int main()
{
    data f();

    f().array;

    return 0 ;
}

【问题讨论】:

  • GCC 究竟是如何在没有一次诊断的情况下编译它的? void f()data f() 没有兼容的类型,clang 以硬错误拒绝它。
  • @hvd 它甚至为我运行。打印hello!
  • @hvd,我也对此感到很困惑,即使-Wall -Wextra -pedantic g++ 没有吐出任何错误。 clang++ 也不在我这边编译。
  • 我不明白所有的反对票,这似乎是一个合理的问题,我希望有人解释为什么f().arrayg++ 下编译并打印hello!。所以它调用了void f(),然后认为你实际上调用了data f(),最后访问了它的成员array?这是荒谬的,clang 不接受此代码(不能通过返回类型重载)。当然,陷入这一切的原因是最令人烦恼的解析,但在我看来,这仍然是一个好问题。
  • @sharth,我知道f() 返回一个数据(至少是main 中定义的版本)。我的问题是:为什么它在g++ 下打印hello!?似乎调用了void f()。而且根本不应该编译这段代码,因为你通过返回类型重载了。

标签: c++ function class


【解决方案1】:

void f() 和以下几行定义了一个函数 f,它接受参数但不返回任何内容。

data f(); 行声明了一个函数 f,它不接受参数,但返回一个 data 类型的对象。由于我们已经看到了f 的定义,我们知道这行实际上是对我们说谎,但是编译器让它说谎,因为它希望与 C 保持兼容,而定义可能是在说谎的人。

明白了吗?

更新:

最初,C 没有void 关键字。所以,要说f() 没有返回任何东西,你只是省略了返回类型——除了设计师是懒惰的打字员,所以他们决定实际上让“未指定类型”意味着“默认为 int”,因为他们是返回整数多于没有。因此,f() 可以定义一个不返回任何内容或返回 int 的函数。我认为编译器实际上很酷,您可以编写 if (x==1) return 5; else return "five"; 之类的内容并让调用函数找出返回值。

这将我们带到data f();。由于您刚刚告诉编译器 f() 返回一个 data 对象,它信任您,并忽略您之前告诉它的内容。当然,在 main() 函数之后,f() 的新声明超出范围,编译器又回到使用 f() 的原始签名。

底线是,虽然合法,但这是非常糟糕的代码 (tm),写它的人应该被扇耳光。

【讨论】:

  • 我在上面(在 cmets 中)问过这个问题,但会再问一次,你能解释一下为什么它首先打印hello(所以void f() 被调用, then behaves like you'd called data f()` 并让访问其成员array?至少这是g++下发生的事情
【解决方案2】:

我不明白这句话:f().array;... 是函数调用吗?还是访问类的属性?

两者兼而有之。它调用函数f,然后访问返回值的array 成员(但不对其进行任何操作,使成员访问毫无意义)。

语句data f();是构造函数的调用?

不,这是一个函数声明。在这种情况下,它应该会报错,因为您已经声明了 fvoid 返回类型。

要声明一个对象,你需要:

data f;          // default-initialisation: leaves the array uninitialised
data f{};        // value-initialisation (since C++11): zero-initialise the array
data f = data(); // value-initialisation (historic): zero-initialise the array

【讨论】:

    猜你喜欢
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    • 1970-01-01
    • 2011-01-04
    相关资源
    最近更新 更多