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?

Reply via email to