In the file /usr/include/dirent.h of MacOSX10.14 I see this line:
struct _telldir; /* forward reference */
In the same file the identifier is used:
struct _telldir *__dd_td;
Nowhere else in the include files is _telldir defined but in the same file the function telldir is declared:
long telldir(DIR *) __DARWIN_ALIAS_I(telldir);
I see the __DARWIN_ALIAS_I macro is defined as
#define __DARWIN_ALIAS_I(sym) __asm("_" __STRING(sym) __DARWIN_SUF_64_BIT_INO_T __DARWIN_SUF_UNIX03)**
I understand this is "inline assembler" and that this defines _telldir but I would like to know more about this definition.
Thanks in advance
It's not exactly inline asm as in instructions, it's just overriding the name mangling for symbol names. (e.g.
static int fooon MacOS normally has a symbol name of_foo. e.g. in the compiler asm output, you'd have_foo: .long 0).In GNU C,
int foo asm("foobar");has an asm symbol name offoobarinstead of the default_foo. See https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html and this SO answer: Adding leading underscores to assembly symbols with GCC on Win32?Try it yourself on https://godbolt.org/ if you're curious.
In this case, we have C preprocessor string literal concatenation of the macro expansions. e.g.
is exactly equivalent to
"_telldir_ino64"in all contexts, including inlong telldir(DIR *dirp) asm("_" "telldir" "_ino64");This use-case appears to be choosing which
telldirimplementation in libc by setting the name based on a few other CPP macros. So if__DARWIN_SUF_64_BIT_INO_Tis defined as"_ino64"and__DARWIN_SUF_UNIX03is defined as empty or/**/, then this sets the symbol name to"_telldir_ino64"(No idea how MacOS would typically actually define those other macros, but the syntax of the line you show is just string literal concatenation inside an
asm("")to set the symbol name.)