我困"undefined reference to vtable..."了一整天。
其实我已经看到很多答案 "undefined reference to vtable..."
例如:
https://gcc.gnu.org/faq.html#vtables
有些人的问题是忘记编写虚拟函数,而其他人则忘记了将.cpp文件添加到生成目录。但是我想我已经注意到了。
A_1并A_2转到共享库libA。A_2源自A_1。A_1.h
#ifndef include_A_1_h
#define include_A_1_h
class A_1
{
public:
A_1() {}
virtual ~A_1() {} // not pure-virtual function has defined
virtual void print() = 0;
private:
};
#endif
Run Code Online (Sandbox Code Playgroud)
A_2.h
#ifndef include_A_2_h
#define include_A_2_h
#include "A_1.h"
class A_2 : public A_1
{
public:
A_2() {}
~A_2() {}
virtual void print();
private:
}; …Run Code Online (Sandbox Code Playgroud) 我在cppreference中看到了这一点。
在范围内查找名称会查找该名称的所有声明,只有一个例外,即“结构hack”或“类型/非类型隐藏”:在同一范围内,名称的某些出现可能引用了声明的
class/struct/union/enum这不是一个typedef,而具有相同名称的所有其它出现要么全部指代相同的变量,非静态数据成员(因为C ++ 14),或枚举,或者它们都指可能过载功能或功能模板名字
上面文本的链接在这里
我不明白什么是“结构破解”和“类型/非类型隐藏”。
他们是同一概念吗?你能给个简单的解释吗?进行摘要演示会很好。
我在这里看不到任何类似于功能测试宏的内容:https: //en.cppreference.com/w/cpp/utility/feature_test
原始文件中似乎都没有提到这两个地方:http : //www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0550r2.pdf
测试__cplusplus也不适当,因为C ++ 20尚未发布,但该功能已经受支持。
功能测试宏支持会在以后的标准化过程中出现,还是增加得太小而不能成为功能测试宏的一部分,因此想要有条件地使用标准版本的人一定会回到老式的手动编译器版本检查中吗?
我们假设以下代码
int __foo(void) {
return 0;
}
int _BAR(void) {
return 3;
}
int main(void) {
return __foo() & _BAR();
}
Run Code Online (Sandbox Code Playgroud)
双下划线和单个下划线后跟一个大写字母符号是保留的,因此不允许(这是一个C++问题,但它也提到了C规则).
我尝试了-Wall -Wextra -pedantic关于gcc的-Weverything选项和关于clang的选项,两者都没有对此发出警告.
有没有办法为此启用编译器警告?
假设我们在成员函数中有以下两个不等式
this <= (void *) &this->data_member
Run Code Online (Sandbox Code Playgroud)
和
&this->data_member < (void *) (this+1)
Run Code Online (Sandbox Code Playgroud)
他们保证是真的吗?(在我检查过的几个案例中,它们似乎都是真的.)
编辑:我错过了&符号,现在这是不正当的正确形式.
以下代码在clang ++中有效,但在g ++中崩溃了
#include<vector>
#include<iostream>
template<class Iterator>
double abs_sum(double current_sum, Iterator it, Iterator it_end){
if (it == it_end)
return current_sum;
return abs_sum(current_sum+std::abs(*it),++it,it_end);
}
int main(int argc, char** argv){
std::vector<double> values {1.0, 2.0,-5};
std::cout << abs_sum(0.0,values.begin(),values.end()) << std::endl;;
}
Run Code Online (Sandbox Code Playgroud)
罪魁祸首证明是这条线:
return abs_sum(current_sum+std::abs(*it),++it,it_end);
Run Code Online (Sandbox Code Playgroud)
在clang中,*it在之前进行评估++it,在g ++中它是相反的,导致迭代器在被解除引用之前被增加.事实证明,评估函数参数的顺序是实现定义的.
我的问题是:我如何捕获此类错误?理想情况下,当我意外地依赖于具体实施细节时,我想要出错或至少发出警告.
即使用-Wall,clang和gcc都不会发出任何警告.
我到处搜索,但可能使用了错误的术语。我还没有找到一个选择。
我发现的唯一问题是这个未解决的问题(但是范围更广):CPP棉绒:您可以对类变量强制使用它吗?。
我知道你不能在void指针上使用指针算法,但理论上你可以对指向void指针的指针进行指针运算,因为它sizeof(void *)会产生指针在你的系统上占用多少字节的答案?
最近我决定深入研究C++标准,检查某些代码片段是否定义明确,以及在标准中找到这些定义的位置.由于标准很难做到(特别是如果你不习惯),我想验证我的假设是否正确.
我遇到了以下示例(这显然是一个坏主意).它编译得很好(使用g ++ 8.2.1)但执行期间SEGFAULTs:
#include <iostream>
static const int staticInt = 23;
int main () {
int &localInt = const_cast<int &>(staticInt);
localInt = 11;
std::cout << staticInt << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以,我搜索了标准(我使用open-std btw 上的工作草案)并找到了第6.8.10段:
在存储中创建一个具有静态,线程或自动存储持续时间的const完整对象占用的新对象,或者在这个const对象在其生命周期结束之前占用的存储内,会导致未定义的行为.
我是对的,本段适用于给定的例子吗?如果我不是,我还应该在哪里看?
是否可以将a包装std::holds_alternative到可变参数模板以将其用于更多类型?
例如:
std::variant<bool, int, double, std::string> var = 4;
bool r = std::holds_alternative<bool, double>(var); // holds either bool or double
Run Code Online (Sandbox Code Playgroud) c++ ×8
c ×2
c++17 ×2
c++20 ×1
clang ×1
clang-format ×1
clang-tidy ×1
const-cast ×1
g++ ×1
gcc ×1
pointers ×1