int i = i;
int main() {
int a = a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
int a = a肯定有未定义的行为 (UB),关于它的更多细节在
读取未初始化的值总是未定义的行为吗?或者有例外吗?.
但是呢int i = i?在 C++ 中,我们可以为全局变量分配非常量值。i在遇到声明之前声明并零初始化(因为它具有文件范围)。在这种情况下,我们将0在定义的后面分配给它。可以说这没有 UB 吗?
C语言中未指定行为的一个示例是评估函数参数的顺序.它可能是左右或左右,你只是不知道.这会影响评估方式foo(c++, c)或foo(++c, c)得到评估.
还有什么其他未指明的行为可以让不知情的程序员感到惊讶?
从C++ 14开始,感谢n3781(它本身没有回答这个问题),我们可能会编写如下代码:
const int x = 1'234; // one thousand two hundred and thirty four
Run Code Online (Sandbox Code Playgroud)
目的是改进这样的代码:
const int y = 100000000;
Run Code Online (Sandbox Code Playgroud)
并使其更具可读性.
下划线(_)字符已经由用户定义的文本采取了C++ 11,和逗号(,)的本地化问题-许多欧洲国家令人困惑†以此作为小数点分隔符-与逗号运算符的冲突,虽然我做的想知道什么样的现实世界的代码可能会被允许,例如1,234,567.
无论如何,更好的解决方案似乎是空间特征:
const int z = 1 000 000;
Run Code Online (Sandbox Code Playgroud)
这些相邻的数字文字标记可以由预处理器连接,就像字符串文字一样:
const char x[5] = "a" "bc" "d";
Run Code Online (Sandbox Code Playgroud)
相反,我们得到了撇号('),我没有被任何我认识为数字分隔符的书写系统使用.
是否有理由选择撇号而不是简单的空间?
†令人费解,因为所有这些语言都在文本中保留了一个逗号"分开"一个原本句子的概念,其句号用于"终止"句子 - 至少对我来说,这非常类似于逗号"分开"一个数字的整数部分和一个句号"终止"它为分数输入做好准备.
假设一个类被定义为
class A {
//.....
};
Run Code Online (Sandbox Code Playgroud)
现在我正在创建两个对象
A a,b;
Run Code Online (Sandbox Code Playgroud)
按照什么顺序a和b创造的呢?它是由标准定义的吗?
就编译器优化而言,将堆分配更改为堆栈分配是否合法和/或可能?或者会破坏as-if规则?
例如,假设这是代码的原始版本
{
Foo* f = new Foo();
f->do_something();
delete f;
}
Run Code Online (Sandbox Code Playgroud)
编译器是否能够将此更改为以下内容
{
Foo f{};
f.do_something();
}
Run Code Online (Sandbox Code Playgroud)
我不这么认为,因为如果原始版本依赖于自定义分配器之类的东西,那将会产生影响.标准是否对此有具体说明?
当使用std::bind绑定成员函数时,第一个参数是对象this指针.但是它可以将对象作为指针传递而不是.
请参阅以下程序:
#include <iostream>
#include <functional>
struct foo
{
void bar(int v) { std::cout << "foo::bar - " << v << '\n'; }
};
int main()
{
foo my_foo;
auto f1 = std::bind(&foo::bar, my_foo, 1);
auto f2 = std::bind(&foo::bar, &my_foo, 2);
f1();
f2();
}
Run Code Online (Sandbox Code Playgroud)
clang和GCC都没有投诉地编译它,结果适用于两个绑定:
foo::bar - 1 foo::bar - 2
我一直试图围绕规范(第20.8.9节),但它是我不太清楚的地方之一.
应该只有一个是正确的,还是都是正确的?
正如初始化所述,需要进行左值到右值的转换?是int x = x;UB吗?C++标准在3.3.2 声明部分中有一个令人惊讶的例子,其中a int用它自己的不确定值初始化:
Run Code Online (Sandbox Code Playgroud)int x = 12; { int x = x; }这里第二个x用它自己的(不确定的)值初始化.- 结束例子 ]
Johannes对此问题的回答表明是未定义的行为,因为它需要左值到右值的转换.
在最新的C++ 14草案标准中N3936,可以在此处找到此示例已更改为:
Run Code Online (Sandbox Code Playgroud)unsigned char x = 12; { unsigned char x = x; }这里第二个x用它自己的(不确定的)值初始化.- 结束例子 ]
C++ 14中有关于不确定值和未定义行为的变化,这些变化在示例中引发了这种变化吗?
我们x是某种类型的先前已初始化的变量.是以下行:
x = std::move(x)
Run Code Online (Sandbox Code Playgroud)
未定义?这个标准在哪里?它对它有什么看法?
序幕:
std::tuple<int, int, int> f();
std::tuple<int, int, float, int> g();
Run Code Online (Sandbox Code Playgroud)
C++ 1z将引入结构化绑定的语法,这样可以编写代替
int a, b, c;
std::tie(a, b, c) = f();
Run Code Online (Sandbox Code Playgroud)
就像是
auto [a, b, c] = f();
Run Code Online (Sandbox Code Playgroud)
但是,std::tie也允许指定std::ignore忽略某些组件,例如:
std::tie(a, b, std::ignore, c) = g();
Run Code Online (Sandbox Code Playgroud)
是否可以使用新的结构化绑定语法执行类似的操作?它会如何工作?
我有一个A类,它有两个静态变量.我想用另一个不相关的静态变量初始化一个,就像这样:
#include <iostream>
class A
{
public:
static int a;
static int b;
};
int A::a = 200;
int a = 100;
int A::b = a;
int main(int argc, char* argv[])
{
std::cout << A::b << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是200.所以,谁能告诉我为什么?