&& 是什么意思?意思是 void *p = &&abc;

发布于 2024-11-08 23:57:37 字数 209 浏览 2 评论 0原文

我遇到了一段代码void *p = &&abc;。这里的&&有什么意义呢? 我了解右值引用,但我认为在此上下文中使用的 && 是不同的。 &&void *p = &&abc; 中表示什么?

I came across a piece of code void *p = &&abc;. What is the significance of && here?
I know about rvalue references but I think && used in this context is different. What does && indicate in void *p = &&abc; ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余生一个溪 2024-11-15 23:57:37

& &是gcc的扩展,用于获取当前函数中定义的标签的地址。

void *p = &&abc 在标准 C99 和 C++ 中是非法的。

使用 g++ 进行编译。

&& is gcc's extension to get the address of the label defined in the current function.

void *p = &&abc is illegal in standard C99 and C++.

This compiles with g++.

第几種人 2024-11-15 23:57:37

如何找到它

这是标签的地址,它是特定于 的功能海湾合作委员会

int main(void) {
    void* startp;
s:
    startp = &&s;
    printf("the assignment above starts at address %p\n", startp);
    return 0;
}

你可以通过测试自己弄清楚:

int main(void) {
    void* startp;
    int a;
    startp = &&a;
    printf("startp=%p\n", startp);
    return 0;
}

在这种情况下,GCC 说:

错误:标签“a”已使用但未定义

在底层 - 汇编

您需要了解汇编程序才能真正理解这一点,但我将尝试向您解释标签地址的含义。

操作系统从磁盘加载 .exe 文件后,操作系统的一个组件称为“加载器”(Windows 有“PE Loader”,Linux 有“ELF 加载器”,甚至可能还有其他组件,如果它们是在kernel),它对该程序进行“虚拟化”,将其变成一个进程。

这个进程认为它是RAM中唯一的一个,并且它可以访问整个RAM(即32位机器上的0x00000000-0xFFFFFFFF)。

(上面只是对正在发生的事情的简短概述,您确实需要学习汇编才能完全理解它,所以请耐心等待)

现在,源代码中的标签基本上是一个地址。 “转到标签;”除了跳转到该地址之外什么也不做(想想汇编中的指令指针)。该标签存储了该 RAM 地址,您可以通过此找到该地址。

学习 ASM 后,您将意识到该地址指向可执行文件的 .text 部分中的指令。 .text 部分保存要执行的程序(二进制)代码。

您可以通过以下方式检查:

objdump -x a.out

实际示例

GCC 中所述,您可以使用它来初始化跳转表。一些扫描仪生成器,例如re2c (请参阅 -g 参数)使用它来生成更紧凑的扫描仪。也许甚至有一个采用相同技术的解析器生成器

How to find it out

That's the address of a label and it's a feature specific to GCC.

int main(void) {
    void* startp;
s:
    startp = &&s;
    printf("the assignment above starts at address %p\n", startp);
    return 0;
}

You could have figured it out yourself by testing:

int main(void) {
    void* startp;
    int a;
    startp = &&a;
    printf("startp=%p\n", startp);
    return 0;
}

In which case GCC says:

error: label ‘a’ used but not defined

Under the hood - assembly

You need to know assembler to really understand this, but I'll try to explain you what an address of a label means.

After the OS loads the .exe file from the disk, a component of the operating system called "the loader" (windows has the "PE Loader", linux has "ELF loader" or maybe even others, if they're compiled in the kernel), it does a "virtualization" of that program, turning it into a process.

This process thinks it is the only one in RAM and it has access to the entire RAM (that is, 0x00000000-0xFFFFFFFF on a 32-bit machine).

(the above is just a short overwiew of what's happenning, you really need to learn assembly to understand it fully, so bear with me)

Now, the label in a source code is basically an address. "goto label;" does nothing else than a jump to that address (think about the instruction pointer in assembly). This label stores this RAM address, and that's how you can find out that address.

After you've learned ASM, you'll realize that that address points to a instruction within the .text section of the executable. The .text section is the one which holds you program's (binary) code to be executed.

You can inspect this with:

objdump -x a.out

A practical example

As described in GCC, you can use this to initialize a jump table. Some scanner generators like re2c (see the -g parameter) use that to generate more compact scanners. Maybe there's even a parser generator employing the same technique.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文