小编Mar*_*tin的帖子

C++ - 为什么这里需要“模板”关键字?

我有以下代码:

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. …

c++ templates dependent-name language-lawyer

10
推荐指数
2
解决办法
554
查看次数

C/C++ - 当我为单个int分配空间时,为什么堆如此之大?

我目前正在使用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,这只是一个测试).

c c++ heap gdb

8
推荐指数
1
解决办法
671
查看次数

Linux内核 - "放置"inode是什么意思?

我在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"的使用在这里更加令人困惑.

linux kernel inode linux-kernel

7
推荐指数
1
解决办法
792
查看次数

typedef int function(void*)的含义是什么?

我使用以下构造看到了一些BSD代码:

typedef int driver_filter_t(void*);
Run Code Online (Sandbox Code Playgroud)

这究竟是什么意思?我不认为它是一个函数指针,因为否则会是这样的typedef int (*driver_filter_t)(void*),对吧?

c bsd typedef function

4
推荐指数
1
解决办法
728
查看次数

如果全局变量的地址被硬编码在 ELF 中,它们如何随机化?

我在几个地方读到过,.data每次程序运行时,ASLR 应该以随机地址加载该部分,这意味着全局变量的地址应该不同。但是,如果我有以下代码:

int global_var = 42;

int main()
{
    global_var = 10;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用 编译它gcc -fpie -o global global.cobjdump -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)

c elf dwarf aslr

4
推荐指数
2
解决办法
939
查看次数

C++ - 将右值引用传递给函数?

我无法理解右值引用的工作原理。我有以下代码:

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)

c++

4
推荐指数
1
解决办法
185
查看次数

C++ - 无符号长长到有符号长长的隐式转换?

我收到 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)

据我了解,当操作两个大小相同但符号不同的整数时,有符号整数将转换为无符号整数,而不是相反。我在这里错过了什么吗?

c++

3
推荐指数
1
解决办法
1086
查看次数

Gdb Python API - 获取PC价值的最有效方法?

我正在寻找一种方法来获取使用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).

python gdb

2
推荐指数
1
解决办法
184
查看次数

Unix:为什么不用env A = 42 echo $ {A}工作?

env手册页说,它会设置指定的环境变量,然后运行指定的命令.知道了,我期待

env A=42 echo ${A}
Run Code Online (Sandbox Code Playgroud)

打印42,但它没有显示任何内容.我究竟做错了什么?

bash env echo

1
推荐指数
2
解决办法
60
查看次数

x86程序集 - 编码相对jmp

我对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

x86 assembly objdump disassembly radare2

1
推荐指数
1
解决办法
170
查看次数

ARM程序集 - 为什么我的应用程序在归零r7时崩溃了?

我在尝试运行一个调用非常简单的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.

c linux assembly gcc arm

0
推荐指数
1
解决办法
738
查看次数