为什么这一行会出错Error: incomplete type is not allowed?
stringstream ss;
Run Code Online (Sandbox Code Playgroud) Lidström先生的主张是,构造shared_ptr<Base> p(new Derived);不要求Base有虚拟析构函数:
Armen Tsirunyan:"真的吗?shared_ptr会正确清理吗?在这种情况下你能否证明可以实现这种效果?"
DanielLidström:" shared_ptr使用自己的析构函数来删除Concrete实例.这在C++社区中被称为RAII.我的建议是你学习RAII的全部内容.它将使你的C++编码在使用时更加容易RAII在所有情况下."
Armen Tsirunyan:"我知道RAII,我也知道,当pn达到0时,最终shared_ptr析构函数可能会删除存储的px.但是如果px有静态类型指针
Base和动态类型指针Derived,那么除非Base有一个虚拟析构函数,会导致不确定的行为.如果我错了,请纠正我."DanielLidström:" shared_ptr知道静态类型是Concrete.它知道这个,因为我在它的构造函数中传递它!看起来有点像魔术,但我可以向你保证它是设计上的并且非常好."
所以,判断我们.如何实现shared_ptr而不需要多态类具有虚拟析构函数是否可能(如果是)?提前致谢
在典型的C++代码中,C++ 17评估顺序保证(P0145)投票的含义是什么?
对于像这样的事情,它有什么变化
i=1;
f(i++, i)
Run Code Online (Sandbox Code Playgroud)
和
std::cout << f() << f() << f() ;
Run Code Online (Sandbox Code Playgroud)
要么
f(g(),h(),j());
Run Code Online (Sandbox Code Playgroud) 我已经看过它多次断言现在C++标准不允许使用以下代码:
int array[5];
int *array_begin = &array[0];
int *array_end = &array[5];
Run Code Online (Sandbox Code Playgroud)
&array[5]在这种情况下是合法的C++代码吗?
如果可能的话,我想要一个参考标准的答案.
知道它是否符合C标准也很有趣.如果它不是标准的C++,为什么决定做出从不同的治疗呢array + 5还是&array[4] + 1?
我最近几天一直遇到这个问题而且我无法理解这里真正发生的事情,或者问题是什么.
我有一个带有这些标志的makefile:
CC = arm-linux-gnueabihf-gcc-4.6
FLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -ftree-vectorize -mfloat-abi=softfp -std=gnu99
Run Code Online (Sandbox Code Playgroud)
我在.a文件中有一个库,它有一些目标文件,我需要做的就是用可执行文件链接它们.我知道原型和所有这些,唯一抱怨的是以下内容:
/usr/bin/ld: error: *EXECUTABLE* uses VFP register arguments, *OBJECTFILE* does not
/usr/bin/ld: failed to merge target specific data of file *OBJECTFILE*
Run Code Online (Sandbox Code Playgroud)
当我不使用-mfloat-abi = softfp时,我得到另一个与浮点寄存器有关的错误.
有没有人知道造成这种情况的原因,以及我可以做些什么来解决这个问题,例如让我的可执行文件不使用虚拟浮点寄存器参数?
x@x:~/Desktop/perf_test$ make
arm-linux-gnueabihf-gcc-4.6 -c -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -ftree-vectorize -std=gnu99 -mfloat-abi=softfp perf_test.c ../baseline/util.c
arm-linux-gnueabihf-gcc-4.6 -o perf_test perf_test.o util.o ../baseline/lib.a
/usr/bin/ld: error: perf_test uses VFP register arguments, perf_test.o does not
/usr/bin/ld: failed to merge target specific data of file perf_test.o
/usr/bin/ld: error: …Run Code Online (Sandbox Code Playgroud) 代码示例:
struct name
{
int a, b;
};
int main()
{
&(((struct name *)NULL)->b);
}
Run Code Online (Sandbox Code Playgroud)
这是否会导致未定义的行为?我们可以辩论它是否"取消引用无效",但是C11没有定义术语"解除引用".
6.5.3.2/4明确指出*在空指针上使用会导致未定义的行为; 但它并没有说同样的->,也没有定义a -> b为(*a).b; 它为每个运营商分别定义.
->6.5.2.3/4中的语义说:
后缀表达式后跟 - >运算符和标识符指定结构或联合对象的成员.该值是第一个表达式指向的对象的指定成员的值,并且是左值.
但是,NULL并没有指向一个对象,所以第二句似乎没有说明.
相关的可能是6.5.3.2/1:
约束:
一元运算
&符的操作数应该是函数指示符,[]一元或一元运算*符的结果 ,或者是一个左值,它指定一个不是位字段的对象,并且不用寄存器存储类说明符声明.
但是我觉得粗体文本是有缺陷的并且应该读取可能指定对象的左值,按照6.3.2.1/1(左值的定义) - C99弄乱了左值的定义,所以C11必须重写它,也许这个部分错过了.
6.3.2.1/1确实说:
左值是一个表达式(对象类型不是void)可能指定一个对象; 如果左值在评估时未指定对象,则行为未定义
但&操作员确实评估了它的操作数.(它不访问存储的值,但这是不同的).
这种长期推理似乎表明代码会导致UB,但它相当脆弱,我不清楚标准的作者是什么意图.如果事实上他们打算做任何事情,而不是让我们讨论:)
考虑以下程序:
extern int x;
auto x = 42;
int main() { }
Run Code Online (Sandbox Code Playgroud)
Clang 3.5接受它(现场演示),GCC 4.9和VS2013不接受(前者的现场演示).谁是对的,C++标准中指定的正确行为在哪里?
经常教授的标准数组大小的宏是
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
Run Code Online (Sandbox Code Playgroud)
或一些等效的形成.然而,当传入指针时,这种事情会默默地成功,并且在运行时看起来似乎有道理,直到事情神秘地分崩离析.
犯这个错误太容易了:一个具有局部数组变量的函数被重构,将一些数组操作移动到一个以数组作为参数调用的新函数中.
所以,问题是:是否有一个"卫生"宏来检测ARRAYSIZEC中宏的滥用,最好是在编译时?在C++中,我们只使用专门用于数组参数的模板; 在C中,似乎我们需要一些方法来区分数组和指针.(例如,如果我想拒绝数组,我只是(arr=arr, ...)因为数组赋值是非法的).
在类中定义的友元函数的完全限定名称是什么?
我最近看到了一个类似于以下的例子.以下完全限定名称是val()什么?
#include <iostream>
namespace foo {
class A {
int x;
public:
A(int x = 0) : x(x) { }
friend int val(const A &a) { return a.x; }
};
}
int main() {
foo::A a(42);
// val() found using ADL:
std::cout << val(a) << std::endl;
// foo::val(a); // error: 'val' is not a member of 'foo'
// foo::A::val(a); // error: 'val' is not a member of 'foo::A'
return 0;
}
Run Code Online (Sandbox Code Playgroud)
参数依赖查找是唯一val()可以找到的方法吗?
不可否认,这并非源于实际问题.我只是希望获得更好的理解.
在 C++17 中有规范文本 [class.mem]/17:
分配具有相同访问控制(第 14 条)的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。具有不同访问控制的非静态数据成员的分配顺序未指定。
还有 [class.mem]/24:
如果标准布局类对象具有任何非静态数据成员,则其地址与其第一个非静态数据成员的地址相同
这里有两个例子:
struct A { int x, y, z; } a;
struct F { public: int p; private: int q; public: int r; } f;
Run Code Online (Sandbox Code Playgroud)
根据上述标准文本,C++17 保证&a.x < &a.y、&a.y < &a.z、 和&f.p < &f.r (但不保证&f.p < &f.q,因为F不是标准布局,所以 class.mem/24 不适用)。
但是,在 C++20 最终工作草案 N4860 中,根据CWG 2404进行了更改。[class.mem]/17 已经变成了 Note。然而,注释在 ISO 标准中是非规范的(意味着编译器供应商可以忽略它们)。我找不到任何其他可能适用的文本。
我的问题是: C++20 是否仍然在某处指定(规范地)保证&a.y < &a.z和/或&f.p < &f.r?或者编译器现在是否有权在所有情况下重新排序类成员,标准布局类的第一个子对象除外? …
c++ ×7
c ×3
arm ×1
arrays ×1
auto ×1
c++17 ×1
c++20 ×1
c11 ×1
class ×1
compilation ×1
destructor ×1
extern ×1
friend ×1
gcc ×1
macros ×1
name-lookup ×1
namespaces ×1
offsetof ×1
standards ×1
stringstream ×1
types ×1