我有以下代码:
template <typename TC>
class C
{
struct S
{
template <typename TS>
void fun() const
{}
};
void f(const S& s)
{
s.fun<int>();
}
};
// Dummy main function
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当使用 gcc 9.2 和 clang (9.0) 构建它时,由于template调用fun. Clang 显示:
error: use 'template' keyword to treat 'fun' as a dependent template name
s.fun<int>();
^
template
Run Code Online (Sandbox Code Playgroud)
我不明白为什么编译器认为fun是 上下文中的依赖名称f,因为f它本身不是模板。如果我改为C普通类而不是模板,错误就会消失;但是,我不明白为什么首先应该出现错误,因为既不S也不f依赖于TC. …
我目前正在使用gdb来查看低级代码的效果.现在我正在做以下事情:
int* pointer = (int*)calloc(1, sizeof(int));
Run Code Online (Sandbox Code Playgroud)
然而,当我info proc mappings在gdb中检查内存时,我看到以下内容之后,我认为是.text部分(因为Objfile显示了我正在调试的二进制文件的名称):
...
Start Addr End Addr Size Offset Objfile
0x602000 0x623000 0x21000 0x0 [heap]
Run Code Online (Sandbox Code Playgroud)
当我所做的只是为一个int分配空间时,堆是怎么回事?
最奇怪的是,即使我正在做calloc(1000, sizeof(int))堆的大小仍然是相同的.
PS:我在x86_64机器上运行Ubuntu 14.04.我正在使用g ++编译源代码(是的,我知道我不应该在C++中使用calloc,这只是一个测试).
我在iput函数顶部看到了以下注释:
/**
* iput - put an inode
* @inode: inode to put
*
* Puts an inode, dropping its usage count. If the inode use count hits
* zero, the inode is then freed and may also be destroyed.
*
* Consequently, iput() can sleep.
*/
Run Code Online (Sandbox Code Playgroud)
对我而言,这听起来不是"放"任何东西,而是"放弃"它.我知道这个drop_inode函数iput在某些情况下被调用,因此术语"put"的使用在这里更加令人困惑.
我使用以下构造看到了一些BSD代码:
typedef int driver_filter_t(void*);
Run Code Online (Sandbox Code Playgroud)
这究竟是什么意思?我不认为它是一个函数指针,因为否则会是这样的typedef int (*driver_filter_t)(void*),对吧?
我在几个地方读到过,.data每次程序运行时,ASLR 应该以随机地址加载该部分,这意味着全局变量的地址应该不同。但是,如果我有以下代码:
int global_var = 42;
int main()
{
global_var = 10;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用 编译它gcc -fpie -o global global.c,objdump -d -M intel显示以下内容:
4004ed: 55 push rbp
4004ee: 48 89 e5 mov rbp,rsp
4004f1: c7 05 3d 0b 20 00 0a mov DWORD PTR [rip+0x200b3d],0xa # 601038 <global_var>
Run Code Online (Sandbox Code Playgroud)
它似乎global_var总是被放置在 601038。事实上,如果我用调试符号编译,global_var的 DIE 会硬编码该地址:
$ gcc -ggdb3 -fpie -o global global.c
$ objdump --dwarf=info global
...
<1><55>: Abbrev Number: 4 (DW_TAG_variable) …Run Code Online (Sandbox Code Playgroud) 我无法理解右值引用的工作原理。我有以下代码:
void f(int&& i)
{}
int main()
{
int i = 42;
int&& r = std::move(i);
f(r);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我收到以下编译器错误:
prog.cpp: In function ‘int main()’:
prog.cpp:46:7: error: cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘int’
f(r);
^
prog.cpp:38:6: note: initializing argument 1 of ‘void f(int&&)’
void f(int&& i)
^
Run Code Online (Sandbox Code Playgroud)
当我显式声明r为右值引用时,为什么编译器认为我正在传递左值?这样做f(std::move(r))似乎有效,但我仍然不明白那里有什么不同。
这是因为在f(r)调用中r被视为左值吗?如果是,是什么类型的std::move(r)?
我收到 clang-tidy 12.0.1 报告的相当奇怪的警告。在下面的代码中:
#include <vector>
int main()
{
std::vector<int> v1;
const auto a = v1.begin() + v1.size();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我看到这个警告被触发:
error: narrowing conversion from 'std::vector<int>::size_type' (aka 'unsigned long long') to signed type 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>::difference_type' (aka 'long long') is implementation-defined [bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions,-warnings-as-errors]
const auto a = v1.begin() + v1.size();
^
Run Code Online (Sandbox Code Playgroud)
据我了解,当操作两个大小相同但符号不同的整数时,有符号整数将转换为无符号整数,而不是相反。我在这里错过了什么吗?
我正在寻找一种方法来获取使用Gdb Python API的PC的价值而不显示PC所指向的位置.例如,如果PC指向main,我想做类似的事情:
print(str(gdb.parse_and_eval("$pc")))
Run Code Online (Sandbox Code Playgroud)
没有它显示在十六进制值旁边.我知道set print symbol off,但由于Gdb将PC视为一个函数指针,它将始终显示它指向的符号.
请记住,我正在寻找一种简单有效的方法(这意味着没有split/ partition).
该env手册页说,它会设置指定的环境变量,然后运行指定的命令.知道了,我期待
env A=42 echo ${A}
Run Code Online (Sandbox Code Playgroud)
打印42,但它没有显示任何内容.我究竟做错了什么?
我对gcc如何编码相对跳跃感到有点困惑.我有以下内容:
int main(void)
{
__asm__ __volatile__(
"jmp label\n"
"label:\n"
"nop\n"
);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
构建this(gcc -c -o test.o test.c)显示以下(objdump -M intel -d test.o):
0000000000000000 <main>:
0: 55 push rbp
1: 48 89 e5 mov rbp,rsp
4: eb 00 jmp 6 <label>
0000000000000006 <label>:
6: 90 nop
...
Run Code Online (Sandbox Code Playgroud)
rasm2 -d eb00显示jmp 2,这意味着正在以2的偏移量执行跳转.现在,我已经理解相对跳跃的偏移量被添加到当前值eip,该值应该指向下一条指令(即nop).这种编码让我觉得偏移是相对于jmp自身的地址.不应该jmp被编码为jmp 0,因为nop已经在label?
我在尝试运行一个调用非常简单的ARM汇编函数的C程序时遇到了一个奇怪的问题.这是我的C代码:
#include <stdio.h>
#include <stdlib.h>
extern void getNumber(int* pointer);
int main()
{
int* pointer = malloc(sizeof(int));
getNumber(pointer);
printf("%d\n", *pointer);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是我的汇编代码:
.section .text
.align 4
.arm
.global getNumber
.type getNumber STT_FUNC
getNumber:
mov r1, #0
str r1, [r0]
bx lr
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是,如果我mov r7, #0在顶部添加一行getNumber,则程序在尝试访问时会出现段错误pointer.在用gdb检查之后,我注意到现在指针本身存储在一个非常低的地址,例如0xa.
现在,我做了一些研究,显然r7是THUMB代码的帧指针(根据这个).但是,我清楚地说明我不想.arm在汇编代码中的行中使用THUMB指令.为什么它失败了?
我正在使用arm-linux-gnueabihf-gcc编译.c和.s文件,我正在运行Arch Linux的基于Cortex-A8的板上运行该程序.
编辑:如果我使用-fomit-frame-pointer标志进行编译,程序运行正常.但是,我仍然想知道为什么使用r7作为帧指针.
编辑2:即使我使用.code 32而不是,它仍然失败.arm.