我正在使用 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) 我有一个仅包含以下内容的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,mov和pop指令并组装(在mac上,我正在使用Clang),结果对象文件要小4个字节.链接和执行结果具有相同的行为和相同大小的可执行文件.
这表明这些指令是多余的 - 为什么编译器会把它们放入?这只是一个留给链接器的优化吗?
确实确实存在一些密切相关的问题,但是我正在努力找出如何应用其解决方案。
我有一个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) 我怀疑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) 不幸的是,我必须在调用第三方库时执行缩小演员.我不想在我的发布版本中施加开销,因此将使用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) 我一直在密切关注的建议从来没有写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)