Chris Lattner wrote:

[Richard E., please see below for a question re. RealView's behavior.]

>> You and Chris are taking the view that "the type" has a location.  But,
>> a lot of people don't look at it this way.  The things that have
>> locations are variables (including class data) and functions.  After
>> all, types don't appear in object files; only variables and functions do.
> 
> That is a limited view of things based on the current implementation of
> GCC.  When future developments (e.g. LTO) occur, this will change: types
> certainly do live in object files.

I don't see how LTO changes this.  Yes, type definitions will appear in
one or more object files.  But, the intended semantics of LTO are just
to do what the linker would do -- plus some consistency checking.

>> Furthermore, you're taking the view that:
>>
>>   __attribute__((visibility ("hidden"))
>>
>> on a type means something about visibility of the type in a linguistic
>> sense, i.e., that it provides some kind of scoping, perhaps like an
>> anonymous namespace that is different in each shared library.
> 
> Yes.

That's a possible meaning, but it's not the meaning that was intended.
As Danny has said, it's not the meaning that Windows users want.  It's
also not the meaning that SymbianOS users want.

>> But, the visibility attribute is only specified in terms of its effects
>> on ELF symbols, not as having C++ semantics per se.  The hidden
>> visibility attribute says that all members of the class have hidden
>> visibility, unless otherwise specified.
> 
> I'll paraphrase this as saying: "this is already an extension, not a
> standard - we can extend the extension without remorse".

Currently, the compiler generates wrong code: it generates a hidden
reference to a dllimport'd function.  There are two ways to fix that:
declare the construct invalid, or make the compiler generate a
non-hidden reference.  The second option might be an "extension to an
extension" but it might also just be "a bug fix".

>> We also allow:
>>
>> struct __attribute__((visibility("hidden"))) S {
>>   __attribute__((visibility("default"))) void f();
>>   void g();
>> };

> Because there is no standard to reference, I think it's important to
> consider these things in terms of explainability.  It is very easy (and
> common) to explain visibility and anon namespaces in terms of types
> (when applied to a type).

Here would be my explanation:

"The visibility attribute to a class specifies the default visibility
for all of its members, including compiler-generated functions and
variables.  You can override that default by explicitly specifying a
different visibility for the members."

That seems acceptably simple to me.  As long as we allow visibility
specifications for the members that are different from the class
(independently of whether that is narrower or wider visibility) an
explanation in terms of namespaces will require a caveat.  For example:

"Giving a class hidden visibility is similar to putting it in an
anonymous namespace shared not just within a single translation unit,
but across all translation units in a shared object.  However, if you
override the visibility of the members of the class, then they may have
more or less visibility than specified by the class."

ELF operates at a level below C++, and can be used to do things that C++
does not allow.  For example, the C++ standard (via the ODR) forbids a
single program from having two classes with the same name.  But, one of
the goals of ELF hidden visibility is to allow that, so that, for
example, two plugins can have classes with the same name without
conflicting.  You can also give two C++ functions the same address via
appropriate ELF magic.  These sorts of things must be done with care,
but they are techniques used by many real programs, and in the hands of
experts, useful.

> I suspect that the realview compiler accepts
> this as an oversight or a bug, not as an intentional feature.

Let's ask.

Richard E., is the fact that RealView 3.0SP1 accepts:

  class __declspec(notshared) S {
    __declspec(dllimport) void f();
  };

a bug or a feature?  If this is considered a bug, is it something that
RealView is likely to change in a future release, or will it be
preserved for the forseeable future for backwards compatibility?

> There are two conflicting goals to balance:
> 
> 1. Define our extensions as well as possible and make their semantics as
> explainable and logical as possible.
> 2. Compile existing code with maximum compatibility.
> 
> To me, the best way to handle this is to reject this by default (based
> on #1).  To handle #2, add a flag (defaulting to off) to enable this
> extended extension.  In the diagnostic, tell the user about the option,
> and in the manual document the option and the issue.

Good; at this point we've agreed that we should accept the code.  Now
we're just arguing about whether we accept it by default.  That's a less
important issue, since at least there will be some way to get the
behavior that users want.

We have accepted this code:

>> struct __attribute__((visibility("hidden"))) S {
>>   __attribute__((visibility("default"))) void f();
>>   void g();
>> };

for quite some time.  It would be surprising to make that an error now.

The question which prompted this debate was where "f" has been marked
"dllimport" rather than with an explicit visibility.  But, "dllimport"
certainly implies default visibility.  It would be inconsistent to
accept the case directly above, but not the "dllimport" case.

-- 
Mark Mitchell
CodeSourcery
[EMAIL PROTECTED]
(650) 331-3385 x713

Reply via email to