为什么int x {y = 5}是可能的?


10
int main() {
    int y;
    int x{ y = 5 };
    //x is 5
}

由于y = 5不是可计算的表达式,这怎么可能?

另外,为什么编译器或IDE不会抱怨main()不返回int?


8
y = 5 一个表达式,它具有值5。您为什么认为不是?
没用的

2
关于缺少return问题main,参见这个问题
胡桃木

3
更好的是,删除第二个问题。一个单一每个问题的问题是对堆栈溢出的优选模型。
StoryTeller-Unslander Monica,

也许您应该重新定义问题,为什么y = 5在这里产生5。赋值运算符返回某些内容的可能性确实是C / C ++的一个怪异功能。
user7860670

Answers:


11

我将从你的最后一个问题开始

另外,为什么编译器或IDE不会抱怨main()不返回int?

根据C ++标准(6.6.1主要功能)

5 main中的return语句的作用是保留main函数(使用自动存储持续时间销毁所有对象)并使用返回值作为参数调用std :: exit。如果控制从main的复合语句的结尾流出,则效果等效于操作数为0的返回(另请参见18.3)。

相对于这个问题

由于y = 5不是可计算的表达式,这怎么可能?

来自C ++标准(8.18赋值和复合赋值运算符)

1赋值运算符(=)和复合赋值运算符均从右到左分组。它们都需要一个可修改的左值作为其左操作数,并返回一个引用左操作数的左值。

Sp此声明

int x{ y = 5 };

可以等效地分为两个语句

y = 5;
int x{ y };

此外,在C ++中,您甚至可以通过以下方式引用变量y

int &x{ y = 5 };

这是一个示范节目

#include <iostream>

int main() 
{
    int y;
    int &x{ y = 5 };    

    std::cout << "y = " << y << '\n';

    x = 10;

    std::cout << "y = " << y << '\n';
}

它的输出是

y = 5
y = 10

你可以这样声明

int x{ y = 5 };

改写也一样

int x = { y = 5 };

但是要考虑到这两个声明(与上述声明类似)之间存在差异。

auto x{ y = 5 };

auto x = { y = 5 };

在第一个声明中,变量x的类型为int。在第二个声明中,变量x的类型为std::initializer_list<int>

为了使差异更明显,请参见如何输出对象的值。

#include <iostream>

int main() 
{
    int y;
    auto x1 { y = 5 };  

    std::cout << "x1 = " << x1 << '\n';

    auto x2 = { y = 10 };   

    std::cout << "*x2.begin()= " << *x2.begin() << '\n';

    std::cout << "y = " << y << '\n';

    return 0;
}

程序输出为

x1 = 5
*x2.begin()= 10
y = 10

16

由于y = 5不是可计算的表达式,这怎么可能?

这是一个赋值,赋值产生值,即“左操作数的cv不合格类型”,请参见[expr.ass / 3]。因此,y = 5结果y5,用于初始化x

关于第二个问题,请参阅main(或[basic.start.main / 5])上的cppreference :

main函数的主体不需要包含该return语句:如果控制在未遇到return语句的情况下到达main的末尾,则其效果就是execute return 0;

因此,编译器或IDE return在末尾警告您丢失语句main将是完全错误的。诚然,您应该始终return从非void函数execptmain对象成为对象这一事实……好吧,我想是出于历史原因。


2
表达式可以产生一个值,但是只有一个函数可以return。-pedantic
没用的

我认为这个int x {y = 5}; 声明在c
bhura中

@bhura-问题是关于C ++,而不是C
StoryTeller-Unslander Monica,

也许值得一提的是,即使不是必需的,通常仍然从main返回一个值被认为是好的做法?
阿空加瓜

4

operator=()一个值,它是分配给变量的值的结果。因此,可以像这样链接分配:

int x, y, z;
x = y = z = 1;

赋值表达式具有。函数具有返回值;表达式没有。
皮特·贝克尔,

3

如果您查看有关cppreference的文档,您会看到该operator=()返回一个对已分配对象的引用。因此,分配可以用作返回分配的对象的表达式。

然后,这只是带括号的普通作业。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.