Chris Lattner wrote:

> This description also makes sense, but is different than what was
> described before.  To me, this description/implementation is extremely
> problematic, because the extension cannot be described without
> describing the implementation (specifically presence of vtables etc),
> which is unlike any standard C++ feature.

That's because it's an ELF-level attribute.  It's like dirty tricks you
can play with the "alias" attribute (means two functions can have the
same address) or making things weak (means addresses of objects with
static storage duration can be NULL).  These things are all unappealing
from a language theory point of view; they explicitly go behind the back
of the language to do odd things.  This is the ugly reality of C/C++,
and also part of why the languages are so useful.

> Some more specific questions:

I'll answer with what I think should happen and with what I know about
what G++ does.  I'm not sure what RealView does in all of these cases.

> 1. If a class is hidden, does that default all the members (not just the
> metadata) to be notshared?

Yes.  (This is what G++ does.)

> 2. If a class with vtable is hidden, what visibility constraints exist
> on virtual methods?

None.  In particular, the virtual methods may be imported from another
shared object.  (However, if a virtual function is hidden, then the
vtable must also be defined in the same shared object, as otherwise you
will get a link error.)

> 3. What does 'notshared' on a class without a vtable mean, what effect
> does it have?

It means that all the members have hidden visibility, unless otherwise
specified.  (This is what G++ does.)

> 4. If classes with vtables have different behavior than those without,
> is this something we want?

There's no difference.

The notshared attribute means that all of the members,
compiler-generated or otherwise, have hidden visibility, unless
otherwise explicitly specified.  It doesn't say anything about the type
per se, just about the various members.

> 5. How does this impact the ODR?

It's beyond the scope of the ODR.  Even for two hidden functions "f",
each defined in different shared objects, the name of both is "::f" --
but is that an ODR violation?  We're way outside the standard at this point.

In practice, people use all of these facilities to do things that
explicitly violate the ODR.  For example, in an implementation DLL:

  struct S {
    __attribute__((visibility("hidden"))) void f();
    __declspec(dllexport) void g();
  };

In other DLLs, the header for S looks like:

  struct S {
    __declspec(dllimport) void g();
  };

and "f" is not even declared.  Certainly, the intent is that these are
the same types, but as a literal reading of the standard that's an ODR
violation.  (Even if you left "f" in, it would be an ODR violation in a
literal sense due to the change from dllexport to dllimport, unless you
modify the ODR rules to be more structural than literal.  They actually
require token-for-token identity.)

That's why the right way to understand these attributes is purely in
terms of what they do to object files.  Yes, that's crossing an
abstraction barrier, and yes, it means that as a programmer, you need to
understand that "there's some vtables and stuff out there", but that's
they way people use these bits in practice.

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

Reply via email to