无法弄清楚这个c语法是什么

时间:2013-07-04 01:11:25

标签: c variable-declaration

我讨厌问这样的语法问题,但是我无法通过搜索找到答案。我不确定每个变量声明的含义。我对第3个问题的最佳猜测是,它采用标签检查点的逻辑和地址以及页面大小的倒数,将其作为无符号长整型,然后将其重新设置为void指针。代码来自此处:http://nmav.gnutls.org/2011/12/self-modifying-code-using-gcc.html

int (*my_printf) (const char *format, ...);
void (*my_exit) (int);
void *page =
  (void *) ((unsigned long) (&&checkpoint) &
    ~(getpagesize() - 1));

谢谢!

3 个答案:

答案 0 :(得分:5)

my_printf是一个返回int的函数的指针,它接受一个char指针参数和一个其他的变量列表。

my_exit是指向没有返回值的函数的指针,带有一个int参数。

page是指向某些未指定类型的指针。它被分配了一个不应该编译的表达式的值,因为&&是一个二元运算符并且没有左操作数,并且一元地址是没有意义的。 & ~(getpagesize() - 1)位掩盖了可能意味着地址的低位,然后指向页面的开头。

一元&&是GNU C扩展,它接受(goto)标签的地址,因此这种结构基本上获取包含该标签的代码页的起始地址。这是特定于编译器和操作系统的东西,而不是C语言的真正部分。

答案 1 :(得分:0)

前两个是分别与printfexit兼容的函数指针。例如。你可以这样做:

my_exit = exit;
my_exit(3);

,这相当于调用exit(3)

你对第三个问题的猜测是正确的。它取决于页面大小始终为2的幂的事实。因此,pagesize-1将具有二进制模式,该模式在低位中全部为1,高位中的所有0都是0。反转它会反转这些位。这可以用作带有地址的位掩码,以返回地址所指向的页面开头的地址。然后,它会将page设置为包含checkpoint的页面的开头。

答案 2 :(得分:0)

int (*my_printf) (const char *format, ...);声明一个返回int的函数指针,并将一个c样式字符串作为第一个参数,在format参数后面有一个可变数量的参数。

void (*my_exit) (int);声明一个不返回任何内容的函数指针,但是接受一个int。

void *page = (void *) ((unsigned long) (&&checkpoint) & ~(getpagesize() - 1));声明一个通用指针,该指针等同于指向页面大小减去1的checkpoint指针的地址。