为什么 gdb 不能在 !=/== 和 &&/||组合在一个表达式中?
Why can't gdb evaulate functions when !=/== and &&/|| are combined in an expression?
可能是我在描述问题时遇到的困难是我找不到其他人提供它的实例的原因。我使用的是gdb 7.4-2012.04。
似乎至少任何一个表达式都包含这两者和&;/||for矢量或矢量迭代器将无法在gdb中进行求值,并出现以下错误:
无法访问地址0x0 处的内存
下面是一个测试用例,后面是我的编译行和测试:
#include <stdio.h>
#include <iostream>
#include <stdint.h>
#include <vector>
using namespace std;
typedef char GUID[32];
int main(int argc, char **argv){
vector<int> vec;
for (int i=0; i<5; i++){
vec.push_back(i);
}
for (vector<int>::iterator vecIter=vec.begin(); vecIter!=vec.end(); vecIter++){
int i=0;//Just need a line gdb will recognize for a breakpoint.
}
cout << vec[0] << endl;//g++ needs to include operator[] in the binary for this to work.
return 0;
}
以下是我执行的测试片段:
user@comp$ g++ -g -O0 any_test.cpp
user@comp$ gdb a.out
(gdb) b 16
(gdb) r
Breakpoint 1, main (argc=1, argv=0x7fffffffe288) at any_test.cpp:16
16 int i=0;//Just need a line gdb will recognize for a breakpoint.
(gdb) p *vecIter == vec[1] or *vecIter == vec[2]
Cannot access memory at address 0x0
原来有用的语句不起作用。让我们减少一点,找出问题所在。
(gdb) p vec[1] or *vecIter == vec[2]
Cannot access memory at address 0x0
(gdb) p vec[1] or *vecIter
$1 = true
(gdb) p 1 or *vecIter == vec[2]
Cannot access memory at address 0x0
问题似乎是"或"之后的"=="。其他运营商也是这样吗?
(gdb) p 1 and *vecIter == vec[2]
Cannot access memory at address 0x0
(gdb) p 1 and *vecIter != vec[2]
Cannot access memory at address 0x0
这是一个响亮的肯定。如果我拔出gdb的所有函数呢?让它取消引用并比较int?
(gdb) p 1 or *vecIter._M_current == vec._M_impl._M_start[1]
$2 = true
好的,让我们检查一些取消引用和函数的组合,以确保问题不仅仅是由以下类型之一引起的:
(gdb) p 1 or *vecIter._M_current == *vecIter
Cannot access memory at address 0x0
(gdb) p 1 or vec._M_impl._M_start[1] == vec[1]
Cannot access memory at address 0x0
正如您所看到的,问题并不特别在于向量或其迭代器。如果在&;/||,并且在===/!=的任一侧。
编辑:又忘了一个问题。我的问题是:为什么我在"p*vecIter==vec[1]或*vecIter==vec[2]"行中得到"无法访问地址0x0处的内存"?
问题出在返回引用的函数中。这里有一个最小的例子:
int& g() { static int i; return i; }
int main() {}
同样的问题也出现了(我使用的是gdb 7.8.1):
(gdb) p 0 || +g()
Cannot access memory at address 0x0
一种变通方法是将引用转换为指针并间接引用:
(gdb) p 0 || +*&g()
$1 = true
提交了一个错误:https://sourceware.org/bugzilla/show_bug.cgi?id=17904
求值"*vecIter==vec[1]"的顺序是先求值*vecIter,如果为true,则跳过求值vec[1],整个语句为true;如果为false,则评估vec[1]。这里的根本原因是vecIter指向无法访问的NULL内存,而*vecIter甚至无法计算。因此gdb打印出"内存访问"错误。
相同错误的其他打印语句的相同原因
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 如何在一个表达式中生成并返回结果?
- 为什么一个表达式中的 std::string 连接给出的结果与逐个字符不同的结果?
- CUDA C++:文件中 kernel.cu 应有一个表达式
- 如何在一个表达式中将 char[] 转换为向量<char>(可移植)
- 无限数组C++在一个表达式中使用两个新值调整数组大小
- 期待一个表达式
- 在不使用lambda的情况下,我如何整齐地创建一个表达式的函数
- C++11-返回一个表达式以确定类型
- 用一个表达式包装变元宏中的每个元素
- 我有 3 个错误:期望一个")",期望一个表达式,long 类型的参数与 U32 类型的参数不兼容
- 计算一个表达式来计算循环
- 为什么 gdb 不能在 !=/== 和 &&/||组合在一个表达式中?
- 在 C++11 中的一个表达式中对同一变量进行双重赋值
- when是lambda函数中的一个表达式
- 如何写一个字符串,看看它是否是一个表达式
- c++标准算法,用最低优先级的运算符分隔一个表达式为两个表达式
- 我如何写一个表达式,在GDB的指针
- 我如何解析一个表达式嵌套括号与boost.Spirit