Sir-G:
SG>Правомерен ли по стандарту такой доступ к приватной структуре?
Да.
SG>То, что компилируется и работает на двух основных компиляторах — это баг или фича?
Фича.
SG>Ссылка на код ideone
SG> // Why do we have access to X::B here?
Потому что типы сами по себе не обладают такой характеристикой, как доступность в некотором контексте. Концептуально доступность — это либо свойство объявления, либо статус базового класса по отношению к производному в определённом контексте.
Если некая конструкция ссылается на какую-то сущность за счёт непосредственного использования недоступного в данном контексте объявления, то такая конструкция некорректна. На один и тот же тип иногда можно сослаться при помощи разных объявлений, одни из которых в некотором месте могут быть доступными, а другие в том же самом месте — недоступными:
class X
{
struct A {};
public:
typedef A B;
};
int main()
{
X::B(); // OK
X::A(); // error
}