您的位置:首页 > 教育 > 锐评 > 关于利用C/C++ 利用编译器RAII机制,在多种编译器及跨平台下得兼容性问题。

关于利用C/C++ 利用编译器RAII机制,在多种编译器及跨平台下得兼容性问题。

2024/10/6 6:02:58 来源:https://blog.csdn.net/liulilittle/article/details/140289076  浏览:    关键词:关于利用C/C++ 利用编译器RAII机制,在多种编译器及跨平台下得兼容性问题。

在C/C++ 之中,我们常常利用RAII机制,来处理某个临时块得初始、及利用编译器自动析构,但这可能存在一定的致命性风险,如果你没有遇到,只是你没有过多的进行了解,挨得毒打太小,导致的。

举几个小例子:

以利用  std::lock_guard<std::mutex> 为例;

定义:

                typedef std::mutex                                          SynchronizedObject;typedef std::lock_guard<SynchronizedObject>                 SynchronizedObjectScope;

例一:

            bool IForwarding::TryRemove(boost::asio::ip::tcp::socket* socket, bool disposing) noexcept {std::shared_ptr<boost::asio::ip::tcp::socket> ptr;IForwarding::SynchronizedObjectScope scope(syncobj_);return Dictionary::TryRemove(sockets_, socket, ptr);}

上述例子,在不同得编译器根平台上面会存在不同得效果,取决于编译器得实现,按照人们显示理解:

在 Dictionary::TryRemove 函数执行完毕以后,其键值通过FAR指针反弹到调用方PTR变量之中。

在调用方 TryRemove 函数执行结束后,先执行 SynchronizedObjectScope 的析构,

在执行 std::shared_ptr 的析构函数,在很多编译器之中是这样,但在一些编译器之中,

它可能不是这样执行的,这就带来了一些不可控制的因素,所以看上去,我们需要例二:

            bool IForwarding::TryRemove(boost::asio::ip::tcp::socket* socket, bool disposing) noexcept {std::shared_ptr<boost::asio::ip::tcp::socket> ptr; {IForwarding::SynchronizedObjectScope scope(syncobj_);return Dictionary::TryRemove(sockets_, socket, ptr);}}

其实这种在所有的编译器当中,都是可以正确执行的,看上去已经完全没有问题了,但当人们启用编译器 -O3、-OX 编译器最大优化时,它在一些编译器及平台上面仍旧会出现问题,所以,这个时候,我们需要例三:

            bool IForwarding::TryRemove(boost::asio::ip::tcp::socket* socket, bool disposing) noexcept {std::shared_ptr<boost::asio::ip::tcp::socket> ptr; do {IForwarding::SynchronizedObjectScope scope(syncobj_);return Dictionary::TryRemove(sockets_, socket, ptr);} while (false);}

上述的代码,在绝大多数编译器及平台上面都可以确保流程跟我们预期的一致性,但仍旧不能保证在优化之后会像例二一般,出现问题,虽然这段代码的编写方式,比例子二在更多的编译器、及平台上面有保证,所以我们需要例子四。

例子四点一:

            bool IForwarding::TryRemove(boost::asio::ip::tcp::socket* socket, bool disposing) noexcept {std::shared_ptr<boost::asio::ip::tcp::socket> ptr; for (;;) {IForwarding::SynchronizedObjectScope scope(syncobj_);return Dictionary::TryRemove(sockets_, socket, ptr);}}

例子四点二:

bool IForwarding::TryRemove(boost::asio::ip::tcp::socket* socket, bool disposing) noexcept {std::shared_ptr<boost::asio::ip::tcp::socket> ptr; bool result = false;for (;;) {IForwarding::SynchronizedObjectScope scope(syncobj_);result = Dictionary::TryRemove(sockets_, socket, ptr);break;}return result;}

以上无论那种形式,都可以在所有的C/C++编译器及平台上面,按照我们预期流程正确执行,在C/C++之中编译器优化。

{ 代码 } ,do { 代码 } while (0, false); 这样的形式,都可能被优化错误,因为在开编译器O3/OX优化时,它们会被编译器预处理,进行栅格退化,退化的结果是不可控制的。

在C/C++ 之中,for (;;) 、while (1) ;;; 是不会被退化的,因为编译器没有这样的优化策略,当然,如果你通过禁用编译器优化的目的,也可以解决问题,只不过这可能不符合,我们的能效预期。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com