在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但我想了解更多关于这个定义的信息。
提前致谢
它不像指令中那样完全是内联 asm,它只是覆盖了符号名称的名称重整。 (例如 MacOS 上的static int foo
通常具有符号名称_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"
在所有上下文中(包括long telldir(DIR *dirp) asm("_" "telldir" "_ino64");
(中完全等同于"_telldir_ino64"
这个用例似乎是通过根据其他一些 CPP 宏设置名称来选择在 libc 中实现telldir
。 因此,如果__DARWIN_SUF_64_BIT_INO_T
定义为"_ino64"
而__DARWIN_SUF_UNIX03
定义为空或/**/
,则这会将符号名称设置为"_telldir_ino64"
(不知道MacOS通常如何实际定义其他宏,但您显示的行的语法只是asm("")
内的字符串文字连接,用于设置符号名称。