小编Rai*_*Rai的帖子

在使用 GCC 的 unordered_map::insert KeyEqual 异常期间内存泄漏 - 打破了强大的异常安全保证?

我正在使用 GCC 7.3.1,但也在coliru 上进行了测试,我认为它是 9.2.0 版。使用以下内容构建:

g++ -fsanitize=address -fno-omit-frame-pointer rai.cpp
Run Code Online (Sandbox Code Playgroud)

这是rai.cpp

#include <iostream>
#include <unordered_map>

int main()
{
    try
    {
        struct MyComp {
            bool operator()(const std::string&, const std::string&) const {
                throw std::runtime_error("Nonono");
            }
        };

        std::unordered_map<std::string, std::string, std::hash<std::string>, MyComp> mymap;
        mymap.insert(std::make_pair("Hello", "There"));
        mymap.insert(std::make_pair("Hello", "There")); // Hash match forces compare
    } catch (const std::exception& e) {
        std::cerr << "Caught exception: " << e.what() << "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

运行它的结果是:

> ./a.out
Caught exception: Nonono

=================================================================
==72432==ERROR: LeakSanitizer: detected memory leaks

Direct …
Run Code Online (Sandbox Code Playgroud)

c++ gcc stl unordered-map exception-safety

10
推荐指数
1
解决办法
312
查看次数

汇编的c ++似乎包含多余的指令

我有一个仅包含以下内容的cpp文件:

void f(int* const x)
{
  (*x)*= 2;
}
Run Code Online (Sandbox Code Playgroud)

我编译:

g++ -S -masm=intel -O3 -fno-exceptions -fno-asynchronous-unwind-tables f.cpp
Run Code Online (Sandbox Code Playgroud)

这导致f.s包含:

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 12
    .intel_syntax noprefix
    .globl  __Z1fPi
    .p2align    4, 0x90
__Z1fPi:                                ## @_Z1fPi
## BB#0:
    push    rbp
    mov rbp, rsp
    shl dword ptr [rdi]
    pop rbp
    ret


.subsections_via_symbols
Run Code Online (Sandbox Code Playgroud)

如果我删除了push,movpop指令并组装(在mac上,我正在使用Clang),结果对象文件要小4个字节.链接和执行结果具有相同的行为和相同大小的可执行文件.

这表明这些指令是多余的 - 为什么编译器会把它们放入?这只是一个留给链接器的优化吗?

c++ macos optimization x86 assembly

8
推荐指数
1
解决办法
168
查看次数

模板类成员函数的C ++部分专业化

确实确实存在一些密切相关的问题,但是我正在努力找出如何应用其解决方案。

我有一个traits类,如下所示,用于处理我正在使用的boost::numeric:ublas::matrix矩阵(以及其他矩阵实现)。我只想对switch_storage_order注释中所示的进行部分专业化,但是由于函数无法部分进行专业化,因此这失败了。

我不想部分专门化该matrix_traits结构,因为这会带来重新定义其所有成员的开销。一种解决方案是将每个与矩阵相关的函数分成各自的结构,但最好将它们分组在一个特征类中。

有任何想法吗?也可以随意评论特质概念的一般应用。

#include <boost/numeric/ublas/matrix.hpp>

enum matrix_storage_order {row_major, column_major};

template<class matrix_type>
struct matrix_traits {
  // Default expects c-style row_major storage order.
  static matrix_storage_order get_storage_order(const matrix_type& m)
  { return row_major; }

  // By default can't change storage order so simply transpose.
  static void switch_storage_order(matrix_type& m) { m.transpose(); }
};

namespace ublas = boost::numeric::ublas;

/* This doesn't work with error C2244:
  * 'matrix_traits<matrix_type>::switch_storage_order' : unable to match function
  * definition to an existing declaration
  */ …
Run Code Online (Sandbox Code Playgroud)

c++ templates partial-specialization

5
推荐指数
1
解决办法
780
查看次数

boost :: optional deprecated get_value_or

我怀疑boost :: optional's get_value_or已被弃用,因为如果将rvalue作为default参数传递则不安全.但是,有时可以引用可选值或默认备选方案.

以下是安全的吗?

template<typename T>
T const& get_reference_or(boost::optional<T> const& opt, T const& alt)
{
    if (opt) return opt.get();
    else return alt;
}

template<typename T>
T const& get_reference_or(boost::optional<T> const&, T&&) = delete;
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference boost-optional

5
推荐指数
1
解决办法
1085
查看次数

带有断言的C++ static_cast

不幸的是,我必须在调用第三方库时执行缩小演员.我不想在我的发布版本中施加开销,因此将使用static_cast.然而,它是一个数组索引,如果它最终消极,可能导致一些娱乐.有没有办法在调试模式下创建一个安全的强制转换,它会检查值以确保在转换过程中没有丢失?我能想到的唯一方法是使用宏,而我宁愿不这样做.

例如,在使用MSVC的发布和调试模式下:

int main() {
  long long ll = std::numeric_limits<long>::max();
  ++ll;
  std::cout << ll << "\n";
  long l = static_cast<long>(ll);
  std::cout << l << "\n";
}
Run Code Online (Sandbox Code Playgroud)

结果输出:

2147483648
-2147483648
Run Code Online (Sandbox Code Playgroud)

使用宏:

template<class to, class from>
to checked_static_cast(const from& from_value) {
  to to_value = static_cast<to>(from_value);
  if (static_cast<from>(to_value) != from_value)
    throw std::runtime_error("Naughty cast");
  return to_value;
}

#ifdef _DEBUG
#define debug_checked_static_cast(to, val) checked_static_cast<to>(val)
#else
#define debug_checked_static_cast(to, val) static_cast<to>(val)
#endif

int main() {
  try {
    long long ll = std::numeric_limits<long>::max();
    ++ll;
    std::cout << ll << …
Run Code Online (Sandbox Code Playgroud)

c++

4
推荐指数
1
解决办法
797
查看次数

std :: move in return语句

我一直在密切关注的建议从来没有写std::movereturn语句中,例如.例如,除了有一些边缘情况.

我相信以下是另一个std::move可能值得的简单例子- 我错过了什么吗?但我不确定为什么,并且将来会改变C++?

#include <iostream>

struct A
{
};

struct C
{
};

struct B
{
    B(const A&, const C&) { std::cout << "B was copied\n"; }
    B(A&&, C&&) { std::cout << "B was moved\n"; }
};

B f()
{
    A a;
    C c;
    //return {a, c}; // Gives "B was copied"
    return {std::move(a), std::move(c)}; // Gives "B was moved"
}

int main() {
    f();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics rvo c++11

1
推荐指数
1
解决办法
448
查看次数