我有一些代码,基本上归结为以下内容:
void bar(bool b, double f)
{
if (b){
double g = f;
}
}
void foo()
{
double f;
bool b = false;
bar(b, f);
}
Run Code Online (Sandbox Code Playgroud)
这里有任何未定义的行为吗?我怀疑有可能是因为我走的是未初始化的值复制double路过时f到bar.也就是说,我没有使用传递,double因为if块不会运行.
此外,如果我double通过参考,一切都会好的:
void bar(bool b, double& f)
Run Code Online (Sandbox Code Playgroud)
然后我不是"使用"一个未初始化的变量,而只是指它.
此代码是否会导致未定义的行为:
#include <vector>
struct S
{
S() {}
int x;
};
int main()
{
std::vector<S> vec(5, S());
}
Run Code Online (Sandbox Code Playgroud)
由于S()默认初始化自动对象,因此其内容不会首先归零,因此x将是不确定的.然后将包含不确定值的对象复制到每个向量位置.
动机:我们可能期望这个行为与std::vector<S> vec(5);不是UB的行为相同(因为C++ 11),所以这是一个容易犯的错误.
正如Praetorian在评论中所提到的,在C++之前,11可以std::vector<S> vec(5);自由地进行5次默认初始化,或者对部分或全部项目使用复制构造函数.
考虑一些代码:
#include <iostream>
int main()
{
using std::cout;
int a=3;
cout << "a="<<a<<"\n";
{
int a=a;
cout << "new a = " << a << "\n";
a=5;
cout << "a = " << a << "\n";
}
cout << "old a = " << a << "\n";
}
Run Code Online (Sandbox Code Playgroud)
我希望它能打印出来
a=3
new a = 3
changed a = 5
old a = 3
Run Code Online (Sandbox Code Playgroud)
但我得到的实际上似乎new a = 0在第二行说.我认为它会像类的构造函数中的初始化列表一样工作,其中可以编写类似的
C::C(int a) : a(a) {}
Run Code Online (Sandbox Code Playgroud)
但由于某种原因,这是不同的.首先,完全删除外部代码不会导致编译错误.所以我认为这int a=a;是有效的.打开所有编译器警告会导致:
test.cpp: In function …Run Code Online (Sandbox Code Playgroud) 为什么以下编译没有错误?:
int main()
{
int x = x; //I thought this should cause an error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
标准中的哪个部分解释了为什么允许这样做?
我注意到了几个Coverity(静态分析工具)错误类型'未初始化的标量变量',这些错误具有很高的影响力.其中很多只是没有初始化的整数.
将它们初始化为零与默认情况下C++的作用有什么不同?
我想使用https://research.swtch.com/sparse中描述的技巧在C++中构建一个密集的整数集.这种方法通过允许自己读取未初始化的内存来实现良好的性能.
如何在不触发未定义行为的情况下实现此数据结构,并且不会与Valgrand或ASAN等工具发生冲突?
编辑:似乎响应者正在关注"未初始化"这个词,并在语言标准的上下文中对其进行解释.对我而言,这可能是一个糟糕的词语选择 - 这里"未初始化"仅意味着它的价值对于算法的正确运行并不重要.显然可以安全地实现这个数据结构(LLVM在SparseMultiSet中实现它).我的问题是,最好和最有效的方法是什么?
我想问为什么使用未初始化的变量被认为是非类型安全的?
我正在阅读本网站上的C++书籍指南中的Bjarne Stroustrup的初学者书(Programming Principles and Practice Using C++).
书中有关于类型安全的部分说明:
程序 - 或程序的一部分 - 在仅根据类型规则使用对象时是类型安全的.例如,在初始化之前使用变量不被视为类型安全的.
然后本书提供了以下代码作为示例:
int main() {
double x; // we "forgot" to initialize
// the value of x is undefined
double y = x; // the value of y is undefined
double z = 2.0+x; // the meaning of + and the value of z are undefined
}
Run Code Online (Sandbox Code Playgroud)
我知道未初始化的局部变量将具有不确定的值,并且读取此变量将导致未定义的行为.我不明白的是它是如何与类型安全相关联的.我们仍然知道变量定义中的类型.
为什么上面代码中的注释表明当2.0和x都是double时,+的含义是未定义的,+是为double + double定义的?
在cpprefernce部分:值类别中,它声明"对象表达式的成员,其中a是rvalue,m是非引用类型的非静态数据成员"是xvalue.在标准(我发现于:N4140,草案C++ 14标准)中,它声明(在第87页)"如果表达式是......一个指定非静态数据成员的类成员访问表达式,则表达式是xvalue对象表达式为xvalue的非引用类型."
我想通过以下代码检查我对此的理解:
struct B { // B for Boring...
int i{0};
};
template <typename T> struct V {
V() { cout << "V" << endl; }
};
template <typename T> struct V<T &> { // Partial Specialization
V() { cout << "V&" << endl; }
};
template <typename T> struct V<T &&> { // Partial Specialization
V() { cout << "V&&" << endl; }
};
int main() {
int i{1};
V<decltype((1))> v1; // V
V<decltype((i))> …Run Code Online (Sandbox Code Playgroud) 这是我的面试问题:
int var = 1;
void main()
{
int i = i;
}
Run Code Online (Sandbox Code Playgroud)
i分配后的价值是多少?它真的是编译器依赖的还是仅仅是未定义的?我在cygwin上的g ++似乎总是给我0.
谢谢
这两个构造函数声明之间有什么区别:
class Fruit {
private:
int price;
public:
Fruit(int x): price(x)
{
}
};
Run Code Online (Sandbox Code Playgroud)
VS
class Fruit {
private:
int price;
public:
Fruit(int x)
{
price = x;
}
};
Run Code Online (Sandbox Code Playgroud)
在继承的情况下我见过的第一个.
据我所知,这不是一个重复的问题.如果你发现一个人可以随意关闭这个问题.