1
13
我假设你希望这是用纯C++模式编译的,并且你不想只编译C中的一些文件,而不需要在C++和后面的链接中编译。 警告说明编译器生成的复制构造函数和赋值很可能与您的结构不符。在结构的末尾使用零大小的数组通常是C的一种方式,它在运行时决定了一个数组,但是在C++中是非法的,但是你可以得到1的类似行为:
这种类型的结构应该是动态分配的——或者使用动态堆栈分配技巧——并且通常不会被复制,但是如果您尝试过,您会得到奇怪的结果:
在此示例中,编译器生成的复制构造函数将精确地分配
如果您仍然希望能够在C语言中编译这个代码,那么您必须通过闭上眼睛来解决这个警告:不要理会那个特定的警告。如果只需要C++兼容性,可以手动禁用复制构造和赋值:
通过声明复制构造函数和赋值运算符,编译器不会为您生成一个(并且不会抱怨它不知道如何生成)。如果您错误地试图在代码中使用这两个私有项,您将得到编译时错误。因为从未调用它们,所以它们可以保持未定义——这也用于避免从类的其他方法中调用它,但我假定没有其他方法。
由于您正在重构C++,所以我还将使默认构造函数私有,并提供一个静态公共内联方法,该方法将负责内容的正确分配。如果还将析构函数设为私有,则可以确保用户代码不会尝试调用
这将确保用户代码不会错误地在堆栈中创建对象,也不会混合对
[*]此处的大小计算有点偏离,并且将过度分配,可能是
|
2
15
如果这是一个msvc编译器(这是警告消息告诉我的),那么您可以使用pragma warning禁用此警告,即:
顺便说一句,关于复制构造函数的消息并不令人毛骨悚然,但是 好东西 因为这意味着,如果btpat中没有未知字节,就无法复制treedatstr的实例:编译器不知道treedatstr有多大(因为0大小的数组),因此拒绝生成复制构造函数。这意味着,你不能这样做:
无论如何,这不应该起作用。 |
3
3
试着换个说法
|
4
2
这个C(反)模式的主要思想是为treedatstr元素获取所需的额外内存;换句话说,分配将使用malloc(sizeof(ou treedatstr)+len完成。 pragma pack用于要求编译器在字段之间不留空格(通常编译器会在结构字段之间留一些未使用的字节以确保对齐,因为在许多现代处理器中,这是一个巨大的速度改进)。 但是请注意,有些架构中,未对齐的访问不仅速度慢…但是完全禁止(segfault),因此这些编译器可以自由地忽略pragma包;使用pragma包的代码本质上是不可移植的。 我想我应该先把双字放在结构中,而这可能不需要一个pragma包;另外一种消除警告的方法是分配一个元素数组,并使用(len-1)额外的字节进行分配。 在C++中,所有这些东西都是相当危险的,因为你基本上是在愚弄编译器,认为对象的大小比实际的要小,并且假定C++是一种复制逻辑语言,这意味着需要麻烦(例如对于只在对象的第一部分起作用的复制构造和赋值函数)。 对于日常使用来说,使用std::vector肯定更好,但这当然会带来更高的代价(双间接,每个树型实例的内存更多)。 我通常不喜欢认为所有其他程序员都是白痴,所以如果使用了这种糟糕的技巧,那么可能有一个高薪的理由…然而,要做出最终的判断,需要进行更深入的检查。 总结:
没有办法“正确”地静默警告,因为代码想要玩脏(C++编译器不喜欢被对象大小欺骗)。如果您在其他对象中使用这个对象,或者作为其他对象的基础,或者通过值传递它,那么无论发生什么坏情况,您都需要它。 |
5
1
如果它在抱怨复制构造函数和赋值运算符函数,那么您不能提供自己的函数吗?如果你不想要他们,把他们宣布为私人。 如果您在没有意识到的情况下分配或复制代码,这可能会在代码的其他地方产生很多错误,在这种情况下,它无论如何都不会工作,因为没有自动生成的错误。 |
6
0
虽然我意识到这是一个老线程,但我想把我的纯C++ 11解决方案提供给OP的问题。其思想是将要分配的对象包装起来,添加填充以将数组中的对象与2个地址的幂对齐,方法如下:
对象填充大小可以在编译时用以下类计算(如果l是2的幂,则返回l,否则返回2的下一次幂gt l):
|
KPM · PHP和MySQL更改登录用户密码表单,不更新密码 6 年前 |
ISemsem · 如何在发出警告时中止python脚本 6 年前 |
Reilly Ford · 对警告感到困惑 7 年前 |
David Kramf · Swift警告信息不清楚 7 年前 |
Ed Mozley · 捕获powershell警告 7 年前 |