考虑这个程序:
#include <stdio.h>
int main(void)
{
unsigned int a;
printf("%u %u\n", a^a, a-a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是不确定的行为?
从表面上看,它a是一个未初始化的变量.所以这指向未定义的行为.但是a^a并且a-a等于0所有的价值a,至少我认为是这样的.有可能有某种方式来证明行为是明确定义的吗?
正如初始化所述,需要进行左值到右值的转换?是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中有关于不确定值和未定义行为的变化,这些变化在示例中引发了这种变化吗?
C++标准包含一个半着名的例子,在3.3.2中的"令人惊讶的"名称查找,"声明点":
int x = x;
Run Code Online (Sandbox Code Playgroud)
这初始化x自身,(原始类型)未初始化,因此具有不确定的值(假设它是一个自动变量).
这实际上是未定义的行为吗?
根据4.1"左值到右值转换",对未初始化的值执行左值到右值的转换是未定义的行为.右手是否x接受这种转换?如果是这样,示例实际上会有未定义的行为吗?
这个lambda递归有效吗?
#include <functional>
#include <iostream>
int main() {
std::function<int(int)> g = [&g](int k) {
return (k ? k * g(k-1) : 1);
};
std::cout << g(10); // 3628800
}
Run Code Online (Sandbox Code Playgroud)
它似乎编译并运行正常,但我很担心g在我初始化它的同一声明中结束.严格有效的1-10级......?
在全局命名空间中给出以下声明:
constexpr int x = x;
Run Code Online (Sandbox Code Playgroud)
这个结构良好吗?
草案C++ 14标准部分3.6.2 [basic.start.init]说:
具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应在任何其他初始化发生之前进行零初始化(8.5).[...]
似乎使得示例定义良好的是x在常量初始化期间使用其自己的值初始化,这将0归因于零初始化.
error: the value of 'x' is not usable in a constant expression
constexpr int x = x;
^
Run Code Online (Sandbox Code Playgroud) 我偶然发现了令我惊讶的行为:
写作时:
int x = x+1;
Run Code Online (Sandbox Code Playgroud)
在C/C++程序中(或者涉及新创建的变量x的更复杂的表达式),我的gcc/g ++编译没有错误.在上述情况下,X之后为1.请注意,前一个声明的范围中没有变量x.
所以我想知道这是否是正确的行为(甚至可能在某些情况下有用)或者只是我的gcc版本或gcc的解析器pecularity.
顺便说一句:以下不起作用:
int x++;
Run Code Online (Sandbox Code Playgroud) 以下C++程序编译得很好(g ++ 5.4至少在调用时发出警告-Wall):
int main(int argc, char *argv[])
{
int i = i; // !
return 0;
}
Run Code Online (Sandbox Code Playgroud)
甚至像
int& p = p;
Run Code Online (Sandbox Code Playgroud)
被编译器吞噬了.
现在我的问题是:为什么这样的初始化合法?是否有任何实际的用例,或者它只是语言的一般设计的结果?
我有以下代码:
// in global scope:
int x = x;
Run Code Online (Sandbox Code Playgroud)
此代码编译时不会对 GCC 和 clang发出警告:
x:
.zero 4
Run Code Online (Sandbox Code Playgroud)
这是明确定义的吗?它是如何工作的?