#include <iostream>
void IsTrue(const bool value) {
if (value) {
std::cout << "value is True!\n";
}
}
int main()
{
IsTrue([]() { ; /* some lambda */ });
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
value is True!
Run Code Online (Sandbox Code Playgroud)
为什么lambda会评估true
GCC和Clang?MSVC无法构建此(无法将lambda转换为bool).
这是编译器错误吗?或者标准的哪一段允许这个?
为什么C++采用免费函数:
std::make_unique(...);
std::make_shared(...);
Run Code Online (Sandbox Code Playgroud)
而不是使用静态成员函数:
std::unique_ptr::make(...); // static
std::shared_ptr::make(...); // static
Run Code Online (Sandbox Code Playgroud)
?
Clang 3.9非常重用临时使用的内存.
此代码是UB(简化代码):
template <class T>
class my_optional
{
public:
bool has{ false };
T value;
const T& get_or_default(const T& def)
{
return has ? value : def;
}
};
void use(const std::string& s)
{
// ...
}
int main()
{
my_optional<std::string> m;
// ...
const std::string& s = m.get_or_default("default value");
use(s); // s is dangling if default returned
}
Run Code Online (Sandbox Code Playgroud)
我们有大量类似上面的代码(my_optional
只是一个简单的例子来说明它).
因为UB所有的clang编译器从3.9开始重用这个内存,而且它是合法的行为.
问题是:如何在编译时检测这种悬空引用,或者在运行时检测清理程序?没有clang消毒剂可以检测到它们.
UPD.请不要回答:"使用std::optional
".仔细阅读:问题不是关于它.
UPD2.请不要回答:"你的代码设计很糟糕".仔细阅读:问题不是代码设计.
这段代码:
#include <iostream>
#include <vector>
using namespace std;
void dump(const std::string& s) {
cout << s << endl;
}
class T {
public:
T() {
dump("default ctor");
}
T(std::nullptr_t) {
dump("ctor from nullptr_t");
}
T(const T&) {
dump("copy ctor");
}
T& operator=(const T&) {
dump("copy operator=");
return *this;
}
T& operator=(std::nullptr_t) {
dump("operator=(std::nullptr_t)");
return *this;
}
T& operator=(const std::vector<int>&) {
dump("operator=(vector)");
return *this;
}
};
int main() {
T t0;
t0 = {};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产出:
default ctor …
Run Code Online (Sandbox Code Playgroud) 这个程序:
#include <iostream>
using namespace std;
struct B {
B() { cout << "B"; }
//B(const B& b) { cout << "copyB"; }
~B() { cout << "~B"; }
};
struct C : B {
};
void f(B b) {
}
int main() {
C c;
f(c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出B~B~B~B
,即三次调用析构函数,为什么?
仅在 MSVC 中。Clang 和 GCC 输出B~B~B
(最有可能是正确的)。
有趣的是:如果你取消对 copy-ctor 的注释,它会输出BcopyB~B~B
,这是正确的(析构函数调用了两次)。
它是 MSVC 编译器中的错误吗?或者这是正确的行为?
(Visual Studio 2019 最新,cl.exe
版本 19.28.29337)
在测试VS2015 C++编译器时,我偶然发现了default
关键字的一个奇怪错误.如果我做:
struct Dummy
{
Dummy() = default;
Dummy(const Dummy &) = delete;
};
int main()
{
const Dummy& ref = Dummy();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我明白了
错误C2280:'Dummy :: Dummy(const Dummy&)':尝试引用已删除的函数
注释:请参阅'Dummy :: Dummy'的声明
但是,如果我使用一个空构造函数
struct Dummy
{
Dummy() {}
Dummy(const Dummy &) = delete;
};
int main()
{
const Dummy& ref = Dummy();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
代码编译.使用g ++或clang运行第一个示例不会产生错误.
为什么在VS2015中使用默认构造函数尝试使用g ++或clang中没有的复制构造函数?
我有一个功能:
int foo(void * ptr)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我可以在C++ 11/14中语法上(不使用编译器警告等)禁用传递除void *
自身以外的指针吗?
例如,现在它可以被称为:
foo(new int(42));
Run Code Online (Sandbox Code Playgroud)
我需要禁用它.
这是悬空指针|参考示例:
#include <string>
#include <string_view>
#include <iostream>
std::string foo() {
return "test";
}
int main() {
std::string_view bar = foo(); // bar is pointed to destructed string
std::cout << bar << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
地址清理程序无法捕获它,至少使用默认选项.是否有可能通过地址消毒剂捕获此类错误?
UPD.
报告了这个bug:
我接近跟随struct检测是否可以通过值传递类型:
template <class T>
struct should_be_passed_by_value {
static constexpr bool value =
std::is_scalar<T>::value ||
std::is_array<T>::value ||
std::is_reference<T>::value ||
(sizeof(T) <= sizeof(void*));
};
Run Code Online (Sandbox Code Playgroud)
问题是:当我为类C函数指针或std :: function实例化它时,编译器说:
invalid application of 'sizeof' to a function type
Run Code Online (Sandbox Code Playgroud)
(当然).
如何修改以便value
包含false
?
更新问题为什么这两个右值引用示例有不同的行为?:
源代码:
int a = 0;
auto && b = a++;
++a;
cout << a << b << endl;
Run Code Online (Sandbox Code Playgroud)
版画 20
是否b
在a++
通话后使用未定义的行为(UB)?也许我们不能使用,b
因为它指的是暂时的?
c++ undefined-behavior rvalue-reference language-lawyer c++11