int main() {
int y;
int x{ y = 5 };
//x is 5
}
由于y = 5不是可计算的表达式,这怎么可能?
另外,为什么编译器或IDE不会抱怨main()不返回int?
y = 5
在这里产生5。赋值运算符返回某些内容的可能性确实是C / C ++的一个怪异功能。
int main() {
int y;
int x{ y = 5 };
//x is 5
}
由于y = 5不是可计算的表达式,这怎么可能?
另外,为什么编译器或IDE不会抱怨main()不返回int?
y = 5
在这里产生5。赋值运算符返回某些内容的可能性确实是C / C ++的一个怪异功能。
Answers:
我将从你的最后一个问题开始
另外,为什么编译器或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
由于y = 5不是可计算的表达式,这怎么可能?
这是一个赋值,赋值产生值,即“左操作数的cv不合格类型”,请参见[expr.ass / 3]。因此,y = 5
结果y
为5
,用于初始化x
。
关于第二个问题,请参阅main(或[basic.start.main / 5])上的cppreference :
main函数的主体不需要包含该
return
语句:如果控制在未遇到return
语句的情况下到达main的末尾,则其效果就是executereturn 0;
。
因此,编译器或IDE return
在末尾警告您丢失语句main
将是完全错误的。诚然,您应该始终return
从非void
函数execptmain
对象成为对象这一事实……好吧,我想是出于历史原因。
return
。-pedantic
如果您查看有关cppreference的文档,您会看到该operator=()
返回一个对已分配对象的引用。因此,分配可以用作返回分配的对象的表达式。
然后,这只是带括号的普通作业。
y = 5
是一个表达式,它具有值5
。您为什么认为不是?