C语言 - 这行代码是什么意思?

11
我试图理解以下这行最糟糕的 C 代码(来自 uboot 项目)的含义:

I am trying to understand what the following line of the worst-ever-seen C code (from uboot project) mean:

rc = ((ulong (*)(bd_t *, int, char *[]))addr) (bd, --argc, &argv[1]);

这是什么?函数调用吗?
能不能让它更易读?

提前感谢您的帮助!


3
可以更易读吗?不行!要搞得难以理解! - mr-sk
这是一个糟糕的程序员术语,意思是“尖叫着运行”。 - Adam Crossland
4
斯特凡诺,我必须承认它有某种洛夫克拉夫特式的质感。 - Adam Crossland
1
将函数指针强制转换为甜点,加上--argc樱桃作为点缀 :o) 实际上这是可读的,只是心理解析可能需要一些时间。顺便说一下,正确的项目地址是:http://www.denx.de/wiki/U-Boot/WebHome - MaR
我现在记得为什么我讨厌C语言了。 - Charles Faiga
显示剩余7条评论
6个回答

35

是的,这是一个函数调用。

它将addr中的值强制转换为一个函数指针,该函数接受(bd_t *, int, char *[])作为参数,并返回一个ulong。然后调用该函数。它可以被简写为:

typedef ulong (*bd_function)(bd_t *bd, int argc, char *argv[]);

bd_function bdfunc = (bd_function) addr;

rc = bdfunc(bd, --argc, &argv[1]);

如果仅仅发生一次这种情况,引入一个typedef可能有点过度,但是我觉得它可以帮助我们将函数指针的类型单独看待。


7
由于typedef使得东西更易读,所以并不过度使用。 - David Thornley
1
这不是过度杀伤,就像抗生素不是对感染的过度反应一样。 - Adam Crossland

12

该代码将 addr 转换为一个函数指针,该函数接受 (bd_t *, int, char *[]) 作为参数并返回一个 long,然后使用参数 (bd,--argc,&argv[1]) 调用它。


3
@Jason:当然可以(而且应该),请看unwind的答案。 - T.J. Crowder
1
《芬尼根的守灵夜》也是可以读懂的,但从中提取意义却相当困难。 - Adam Crossland
@T.J. Crowder:这只是将所感知的不可读性移动到其他地方。(需要明确的是,我并不认为任何一个版本都是不可读的。只是如果有人发现原始版本难以阅读,将一部分不可读性转移其他地方并不能减少不可读性。) - jason
@Stephen:许多C程序员,特别是新手,很少需要处理函数指针。此外,如果您必须使用指针类型,则在声明函数的同一头文件中声明指针类型是更好的编程实践,这样,如果您需要更改函数,则不会破坏每个手动编码的转换。在我看来,这是维护101。 - T.J. Crowder
@Jason:我不同意,原因在我对Stephen的评论中。但没关系,聪明人之间可以有不同的看法。 :-) - T.J. Crowder
显示剩余4条评论

4

虽然不是直接回答你的问题,但以下内容可能会有所帮助:

从变量名开始(或者最内层结构如果没有标识符)。向右看,但不要跳过右括号;说出你看到的。再向左看,但不要跳过括号;说出你看到的。如果有任何括号,则跳出一个级别。向右看,说出你看到的。向左看,说出你看到的。继续这样做,直到说出变量类型或返回类型。


2

addr必须是指向内存中类似以下函数的位置

ulong *funcname(bd_t*, int, char*[])

它被称为参数调用,如下所示:

rc = funcname(bd, --argc, &argv[1]);

2

ulong (*)(bd_t *, int, char *[]) 是一个函数类型,它接受一个指向 bd_t 的指针,一个 int 和一个指向 char 数组的指针,并返回一个 ulong

代码将 addr 转换为这样的函数,并使用 bd--argc&argv[1] 作为参数调用该函数,并将结果赋值给 rc


1
你正在将“addr”强制转换为返回ulong的函数指针,该函数以bd_t *、int和char * []作为参数,并使用参数bd、--argc和&argv [1]调用该函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接