On Friday, September 16, 2005, at 10:19 AM, Jonathan Turkanis wrote:
> I think I can give you an answer which is completely correct and yet
> completely useless: -fvisibility=default is supported on every
platform.
Thank you -- it's not completely useless.
It is.
I don't want to recommend that users supply -fvisibility=default
Telling users to supply that flag is useless. It is the default.
Conceptually, you would want to tell them to not use
-fvisibility=hidden.
if it will result in an 'unrecognized option' error on some platforms.
I sense a joke lurking here.
We are confounded as to why you would want to tell a users to specify a
flag that is the default. After reading to the end of your email, I
now understand your question better.
> As Mike says,
>> If you tell us what the real question is, maybe we can answer that
one.
To me, that sounds like an insult
No, we just have enough experience and knowledge, and we actually do
want to help you, but we know enough to know you are hiding the real
question from us, and we know that you need the real answer, but we
can't give it to you, since we don't have the question.
: why do you think I wouldn't ask the "real" question?
Experience.
The docs for -fvisibility say: "Set the default ELF image symbol
visibility to the specified option —- all symbols will be marked with
this unless overridden within the code...."
You can read this without the word ELF and is looses nothing, in fact,
it would be more accurate.
So it seems a fair question to ask where -fvisibility is supported. An
answer that isn't "completely useless" would be appreciated.
M-x grep VISIBILITY tells you the answer. The answer, is precisely on
darwin, and all platforms whose in tree gas assembler is elf whose
version is 2.13 and above or if the assembler accepts:
.hidden foo
without returning a non-zero return code from the assembler and the
linker is 2.13 and above if in tree, otherwise as long as the linker
isn't older than 2002-04-04 or people mussed up the version string of
the linker or is 2.12.0 or older we suppose symbol visibility.
Now, did that precisely answer your question?
Compare that with, every interesting platform now supports visibility
default/hidden.
I'm trying to decide what recommendations to make with repect to
-fvisibility for a forthcoming O'Reilly C++ book.
Gosh, now we have a hint at the real question. I suspect the answer
is, go ahead and use it
At first it looked like a nice way to enable Windows-style exporting
of symbols from dynamic libraries on some UNIX/Linux platforms. Now it
appears that there may be some serious problems with it, at least as
currently implemented. See e.g.,
http://article.gmane.org/gmane.comp.lib.boost.build/10072 and
http://article.gmane.org/gmane.comp.lib.boost.build/10110. Those
threads were also the first indication I had that -fvisibility was
supported on some non-ELF platforms.
I don't have time to verify the assertions made in that thread -- the
book went into production in August -- but I trust the author and he
seems to have conducted some careful experiments. I'm now inclined
just to say that the option, together with the attribute, offered the
possibility of Windows-style exporting on some (unspecified)
platforms, but that initial implementation is buggy;
-fvisibility=default should be specified everywhere, until further
notice.
Ah, now we can start getting to the meat of the question.
Buggy? I think I might disagree with that assessment if you are
referring to the inability to catch hidden types across the hidden
boundary.
Anyway, the real issue boils down to some rather simple concepts.
Suppose someone has:
class A {
};
in one part of their program and:
class A {
};
in another part of their program. The question is, are they the same?
The answer in non-shared library, non-dlopen(), trivial systems, yes.
This is visibility default. When people want them to be different,
then one erects a fence around one or the other, to prevent them from
being the same. visibility hidden, in any of its forms, does that.
The problems the boost people saw were, they wanted an A, that was
across the fence to be the same as the other A on the near side of the
fence, this is illogical, I might claim, and does not indicate a buggy
compiler.
For you to defend it as a buggy compiler, you'd have to explain by what
mechanism you want to mark the two As as being separate. My claim
would be that visibility hidden is exactly that mechanism.
Now, if you are asking how to mark the types as default when
-fvisibility=hidden is used, gosh, could have sworn there was a way to
do it, but someone seems to have broken every incantation I tried. :-(
That to me seems to be a bug.
__attribute__ ((visbility("default"))) class A {
virtual void foo();
};
A a;
void A::foo() {
}
and
class __attribute__ ((visbility("default"))) A {
virtual void foo();
};
A a;
void A::foo() {
}
seem like they both should work and when -fvisibility=hidden is used,
it should cause the rtti information/vtable information and so on to
not be hidden.
Do you know of off hand where Microsoft puts the magic string to export
the class? Do they even have a concept of not exporting the class?