复杂的C演员解释

Ton*_*ion 8 c casting void

我想弄清楚C中的以下代码是做什么的?

((void(*)())buf)();
Run Code Online (Sandbox Code Playgroud)

其中'buf'是一个char数组.

Tho*_*mas 21

让我们一步一步.

void(*)()
Run Code Online (Sandbox Code Playgroud)

这是一个指向函数的指针,该函数接受未指定的参数且没有返回值.

(void(*)())buf
Run Code Online (Sandbox Code Playgroud)

只需将buf转换为此函数指针类型.最后,

((void(*)())buf)();
Run Code Online (Sandbox Code Playgroud)

调用此功能.

所以整个语句"解释buf为指向void没有参数的函数的指针,并调用该函数."

  • 请注意,C不保证数据指针的大小与函数指针的大小相同. (4认同)
  • @vonolsson:除了指针大小之外,C不保证在堆栈或堆上分配的内存是可执行的.此代码应仅出现在JIT或等效代码中,并且必须是特定于平台的.假设buf刚刚被机器指令填充,引用的强制转换之前的行应该是某种特定于平台的操作来刷新icache. (4认同)
  • 将字符缓冲区转换为函数并调用它是邪恶的.它要么是自我修改代码的尝试,要么是恶意进行某种攻击.无论哪种方式,不惜一切代价避免它. (3认同)
  • -1(不是真的):在C中接受未指定的参数 (3认同)

Wer*_*sey 9

它转换buf为类型的函数指针void(*)()(一个函数返回任何/ void并采用未指定的参数)并调用它.

ANSI标准实际上不允许将正常数据指针转换为函数指针,但您的平台可能允许它.


Sha*_*hin 5

当我遇到令人难以置信的声明时,我倾向于使用"cdecl"命令.例:

[me@machine]$ cdecl
Type `help' or `?' for help
cdecl> explain (void(*)())buf
cast buf into pointer to function returning void
Run Code Online (Sandbox Code Playgroud)

虽然有些情况我希望有一个工具可以解释"cdecl"的输出:/