你有任何恐怖故事要讲吗?GCC手册最近添加了一个关于-fstrict-aliasing的警告并通过联合转换指针:
[...]获取地址,强制生成指针并取消引用结果具有未定义的行为 [强调添加],即使转换使用了联合类型,例如:
union a_union {
int i;
double d;
};
int f() {
double d = 3.0;
return ((union a_union *)&d)->i;
}
Run Code Online (Sandbox Code Playgroud)
有没有人有一个例子来说明这种未定义的行为?
请注意,这个问题不是关于C99标准所说或不说的.它是关于gcc和其他现有编译器的实际功能.
我只是猜测,但一个潜在的问题可能在于设置d为3.0.因为d是永远不会直接读取的临时变量,并且永远不会通过"稍微兼容"的指针读取,所以编译器可能不会费心去设置它.然后f()将从堆栈中返回一些垃圾.
我的简单,天真,尝试失败了.例如:
#include <stdio.h>
union a_union {
int i;
double d;
};
int f1(void) {
union a_union t;
t.d = 3333333.0;
return t.i; // gcc manual: 'type-punning is allowed, provided...' (C90 6.3.2.3)
}
int f2(void) {
double d = 3333333.0;
return ((union a_union *)&d)->i; // gcc …Run Code Online (Sandbox Code Playgroud) 我迷失了吗?这总是允许的吗?
#include <iostream>
int main()
{
auto& os = std::cout;
auto write = []()
{
os << "what\n";
};
write();
}
Run Code Online (Sandbox Code Playgroud)
我正在使用:
Apple LLVM 10.0.0版(clang-1000.10.44.4)
目标:x86_64-apple-darwin17.7.0
虽然也看到Coliru:
我一直认为空捕获不会捕获任何东西.
的确,MSDN 说:
空捕获子句[]表示lambda表达式的主体不会访问封闭范围中的变量.
进一步的研究表明,这实际上可以捕捉const东西(我也不知道,但无论如何),但os不是const(没有参考!虽然它是不可改变的......).
当我打开-Wextra并注意到Clang认为&os捕获(存在于我的真实代码中)是不必要的时候,我偶然发现了这一点.删除它我错开了发现构建工作.
#include <iostream>
struct uct
{
uct() { std::cerr << "default" << std::endl; }
uct(const uct &) { std::cerr << "copy" << std::endl; }
uct( uct&&) { std::cerr << "move" << std::endl; }
uct(const int &) { std::cerr << "int" << std::endl; }
uct( int &&) { std::cerr << "int" << std::endl; }
template <typename T>
uct(T &&) { std::cerr << "template" << std::endl; }
};
int main()
{
uct u1 ; // default
uct u2( 5); // int
uct u3(u1); …Run Code Online (Sandbox Code Playgroud) c++ copy-constructor constructor-overloading function-templates overload-resolution
在下面的代码中,while ( !Ref.expired() );快乐地优化为无限循环.如果代码行更改为while ( !Ref.lock() );.一切都按预期工作.真的有两个问题:
1)当std::weak_ptr::expired()访问内存隔离计数器时,编译器如何优化过期?
2)Ref.lock()实际上是安全的,还是可以将其优化掉?
示例代码如下.
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
class A
{
public:
A()
{
m_SomePtr = std::make_shared<bool>( false );
}
virtual ~A()
{
std::weak_ptr<bool> Ref = m_SomePtr;
m_SomePtr.reset();
// Spin (will be optimised into an infinite loop in release builds)
while ( !Ref.expired() );
}
std::shared_ptr<bool> GetPtr() const { return m_SomePtr; }
private:
std::shared_ptr<bool> m_SomePtr;
};
class B
{
public:
B( std::shared_ptr<bool> …Run Code Online (Sandbox Code Playgroud) 在本讲座中,发言者提到(一开始)标准库中没有纯虚函数(或者他没有注意到).我相信Alex Stepanov反对这种语言功能但是从最初的STL设计开始,是否有任何纯粹的虚拟内容进入标准库?
FWIW(并纠正我,如果我错了)唯一指针中的删除器最终在大多数实现中使用虚拟调度,但这些不是纯虚拟.
c++ virtual-functions pure-virtual c++-standard-library language-lawyer
我在shared_ptr和weak_ptr一起使用时遇到了麻烦enable_shared_from_this。
当我用Google搜索所见事物的症状时,每个人都建议“ shared_from_this()当没有shared_ptr实例拥有您的对象时,您将无法使用。
但这不是我的情况。
考虑以下代码:
#include <memory>
#include <cassert>
class MyClass : std::enable_shared_from_this<MyClass>
{
public:
void this_fails()
{
// Doesn't even assert(), because it throws bad_weak_ptr
assert(shared_from_this());
}
void this_fails_too()
{
std::weak_ptr<MyClass> weak = weak_from_this();
std::shared_ptr<MyClass> strong = weak.lock();
// This assert fails
assert(strong.get());
}
};
int main()
{
std::shared_ptr<MyClass> obj = std::make_shared<MyClass>();
obj->this_fails();
obj->this_fails_too();
}
Run Code Online (Sandbox Code Playgroud)
两种方法都会MyClass使程序崩溃。我一定缺少明显的东西-这是什么?
c++ shared-ptr weak-ptr private-inheritance enable-shared-from-this
当我参加C++标准委员会会议时,他们正在讨论删除继承构造函数的优缺点,因为还没有编译器供应商实现它(用户没有要求它的意义).
让我快速提醒大家继承构造函数是什么:
struct B
{
B(int);
};
struct D : B
{
using B::B;
};
Run Code Online (Sandbox Code Playgroud)
一些供应商提出使用r值引用和可变参数模板(完美转发构造函数),在继承类中提供可以避免继承构造函数的转发构造函数是微不足道的.
例如:
struct D : B
{
template<class ... Args>
D(Args&& ... args) : B(args...) { }
};
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
1)您能否从编程经验中提供真实世界(非人为的)示例,这些示例将从继承构造函数中获益匪浅?
2)您是否有任何技术原因可以将"完美的转发建设者"排除在适当的替代方案之外?
谢谢!
我一直假设std::move()a上会std::shared_ptr窃取指针并将原始指针设置为nullptr-从而不增加引用计数。在我的世界中似乎并非如此。
设置:
MacOS,g ++ -version =>“ Apple LLVM版本10.0.1(clang-1001.0.46.3)”
代码:
#include <cstdio>
#include <memory>
class Thing { public: Thing(int N) : value(N) {} int value; };
void print(const char* name, std::shared_ptr<Thing>& sp)
{ printf("%s: { use_count=%i; }\n", name, (int)sp.use_count()); }
int main(int argc, char** argv) {
std::shared_ptr<Thing> x(new Thing(4711));
print("BEFORE x", x);
std::shared_ptr<Thing> y = std::move(x);
y->value = 4712;
print(" AFTER x", x);
print(" AFTER y", y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
编译( …
当有人问decltype(a)及 和之间的区别时decltype((a)),通常的回答是 -a是一个变量,(a)是一个表达式。我觉得这个答案并不令人满意。
首先,a也是一个表达式。主要表达式的选项包括 -
更重要的是, decltype 的措辞非常非常明确地考虑了括号:
For an expression e, the type denoted by decltype(e) is defined as follows:
(1.1) if e is an unparenthesized id-expression naming a structured binding, ...
(1.2) otherwise, if e is an unparenthesized id-expression naming a non-type template-parameter, ...
(1.3) otherwise, if e is an unparenthesized id-expression or …Run Code Online (Sandbox Code Playgroud) 存储是释放操作,负载是两者的获取操作.我知道这memory_order_seq_cst意味着要为所有操作强加一个额外的总排序,但是我没有建立一个例子,如果所有的操作memory_order_seq_cst都被替换,那就不是这样了memory_order_acq_rel.
我是否会遗漏某些内容,或者差异仅仅是文档效果,即memory_order_seq_cst如果有人打算不使用更轻松的模型并且memory_order_acq_rel在约束轻松模型时使用,则应该使用?
c++ ×9
c++11 ×4
shared-ptr ×3
c ×1
c++17 ×1
constructor ×1
decltype ×1
gcc ×1
inheritance ×1
lambda ×1
macos ×1
memory-model ×1
pure-virtual ×1
stdatomic ×1
unions ×1
visual-c++ ×1
weak-ptr ×1