Hmm. Is it really?
I guess we have different ideas of what "equivalent" means. The
behavior suggests that "external" is the LLVM construct a front-end
would use to implement C-type "extern," which is precisely the kind of
knowledge I am after but not how I would use "equivalent."
But too many years of thinking about stuff with names like
"diffeomorphism" may have somewhat altered my usage of "equivalent" from
the mainstream and toward the mathematical.
I made no claim that 'external' in LLVM has the same semantics as
'extern' in C.
And the semantics available in LLVM is the sort of knowledge I seek.
Apparently, the program is working.
LLVM IR is not C, and it is not designed for #includes or other
related horrible C constructs.
Well, there is no question about the horribleness of having to maintain
parallel declarations in a different file from your definitions, or any
of the other hideous consequences of pure textual manipulation by a tool
without syntactic knowledge. But the problem from the standpoint of the
problem I chose to solve is that there is *no* solution within LLVM. As
bad as CPP is, not having it is far worse unless you do the Right Thing
and extend C to make it unnecessary. The analogous situation is that I
work with what LLVM itself provides, and therefore as bad as #include is
the alternative would be to have hand-maintained parallel declarations
of a function in ever file that calls it.
Note that this is *not* intended as a criticism of LLVM. I am perfectly
aware that it was not designed for hand-coding and expects the front-end
to implement whatever tools are necessary. A front-end could generate
such declarations easily, for example. So I seem to have achieved what
I sought--knowledge. I did not know before where the semantics of C's
"extern" were implemented. Now I do--they are implemented by the
front-end, which is responsible for deciding in which module to emit the
definition instead of the declaration.
In fact, much of the fun in life comes from abusing tools for uses they
were never intended for. So far, I still think I am learning more
about LLVM IR by doing this than I would by any other means. I think I
understand by reading, but very often I do *not* until I actually try to
use it. As in this case.
But I did suggest one preprocessor-free alternative for this particular
case: just stick the definition in every source file that needs it and
rely on the linker to merge all references. The docs suggest that is
what "linkonce" is for, but I have already learned I know nothing about
linkage. I can't tell the practical usage difference between linkonce
and any of the other linkages that merge definitions. Which, therefore,
is another opportunity to learn. Which, if any, is most appropriate for
this sort of thing? The goal is learning the idiomatic means, not just
finding a workable kludge.