>> Normally, the version identifier is applied to a type. It then >> propagates to any declaration using that type, whether it's another >> type or function or variable. For struct/union/class types, if any >> member or base class has an attached version identifier (excluding >> static data members, static member functions, and non-virtual member >> functions), we attach the version identifier to the enclosing type. > > How does this handle incomplete types? When we see a forward declaration of > a class, we don't know its member/base types, so we can't propagate.
I believe we required an explicit attribute on the forward declaration in such a case. The compiler would complain if the version_id on the forward declaration didn't match that of the definition, allowing us to catch these cases at compile time (at least if the forward declaration and the definition are ever visible in the same translation unit). In practice, this was a mechanism of last resort, and it was used infrequently enough (I think struct utsname may have been the only type we were using it for when I left) that the known loopholes were not a real concern. (Other known loopholes included assembly code, Fortran, and typecasting.) -cary