0

在 MacOSX10.14 的文件 /usr/include/dirent.h 中,我看到这一行:

struct _telldir;        /* forward reference */

在同一个文件中使用了标识符:

 struct _telldir *__dd_td;

包含文件中的其他任何地方都没有定义 _telldir,但在同一个文件中声明了函数 telldir:

long telldir(DIR *) __DARWIN_ALIAS_I(telldir);

我看到 __DARWIN_ALIAS_I 宏定义为

#define __DARWIN_ALIAS_I(sym)       __asm("_" __STRING(sym) __DARWIN_SUF_64_BIT_INO_T __DARWIN_SUF_UNIX03)**

我知道这是“内联汇编程序”并且它定义了 _telldir 但我想了解更多关于这个定义的信息。

提前致谢

4

1 回答 1

0

它不完全像指令中的内联汇编,它只是覆盖了符号名称的名称修饰。(例如static int foo,在 MacOS 上,符号名称通常为_foo. 例如在编译器 asm 输出中,您将拥有_foo: .long 0)。

在 GNU C 中,int foo asm("foobar");有一个asm 符号名称foobar而不是默认的_foo. 请参阅https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html和这个 SO 答案:在 Win32 上使用 GCC 将前导下划线添加到程序集符号?

如果您好奇,请在https://godbolt.org/上亲自尝试。


在这种情况下,我们有宏扩展的C 预处理器字符串文字连接。例如

"_" "telldir" "_ino64"

在所有情况下都完全等价"_telldir_ino64"于,包括在
long telldir(DIR *dirp) asm("_" "telldir" "_ino64");

这个用例似乎是telldir通过基于其他一些 CPP 宏设置名称来选择 libc 中的哪个实现。因此,如果__DARWIN_SUF_64_BIT_INO_T定义为"_ino64"并且__DARWIN_SUF_UNIX03定义为空或/**/,那么这会将符号名称设置为"_telldir_ino64"

(不知道 MacOS 通常如何实际定义这些其他宏,但您显示的行的语法只是在 an 内连接字符串文字asm("")以设置符号名称。)

于 2019-10-04T10:16:42.053 回答