Re[5]: Восстановил (msvc only)
От: _NN_ www.nemerleweb.com
Дата: 28.09.18 13:22
Оценка: 10 (1)
Здравствуйте, rg45, Вы писали:

2017 в режиме стандартного С++ (/permissive-) не собирает как положено
https://blogs.msdn.microsoft.com/vcblog/2016/11/16/permissive-switch/

error C3861: 'privateMemerAccessEnablerAux': identifier not found
note: 'privateMemerAccessEnablerAux': function was not declared in the template definition context and can be found only via argument-dependent lookup in the instantiation context
note: see reference to alias template instantiation 'PrivateMemberAccess<A_value>' being compiled

http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Восстановил (msvc only)
От: rg45 СССР  
Дата: 28.09.18 13:25
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>

_NN>error C3861: 'privateMemerAccessEnablerAux': identifier not found
_NN>note: 'privateMemerAccessEnablerAux': function was not declared in the template definition context and can be found only via argument-dependent lookup in the instantiation context
_NN>note: see reference to alias template instantiation 'PrivateMemberAccess<A_value>' being compiled


Ну, ожидаемо, в принципе. Они часто запаздывают, но рано или поздно чинят.
--
Re[7]: Восстановил (msvc only)
От: _NN_ www.nemerleweb.com
Дата: 28.09.18 13:34
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Ну, ожидаемо, в принципе. Они часто запаздывают, но рано или поздно чинят.

Где Кодт с решением проблемы ?

Может в reddit подкинуть , глядишь кто-нибудь найдёт лазейку ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: [Trick] Легальный способ доступа к закрытым членам
От: ViTech  
Дата: 28.09.18 13:46
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, ViTech, Вы писали:


_NN>В том и дело, что в специализации можно использовать decltype, но за пределами уже нельзя.

_NN>Например тут как добраться до MemberPtr ?

Я показал способы, как добраться до decltype(&A::m_value) внутри специализации. Действительно, толку от этого мало, потому как тип нужен снаружи. Надо думать, как отвязаться от зависимости decltype(&A::m_value) в параметре шаблона после того, как доступ к нему получен. Может что-то в таком ключе:
template <>
struct X<SomeTag, decltype(&A::m_value)>
{
    using MemberPtr = typename K<X>::MemberPtr;

    SomeTag::???? ????MemberPtr
    SomeTrait<SomeTag>::???? ????MemberPtr
};

Может в какую-нибудь статическую переменную указатель сохранить (как pointerToMember в начальном примере). Но для этого тоже тип нужен, если только void* не использовать .

_NN>X<decltype(&A::m_value)::MemberPtr не скомпилируется.

И правильно сделается, а то слишком просто было бы .

Во всей этой истории мне интересно, зачем в стандарте такое исключение сделали. Явно не для того, чтоб кто угодно мог по приватным данным шарить. Предполагаю, это нужно, чтобы была возможность специализировать шаблоны для типов из приватных секций(чтоб костыли не писать и в публичных секциях эти типы показывать). Соответственно, пользоваться этими специализациями могут только те, у кого есть доступ к приватным типам, а не все подряд. Есть ещё мысли на этот счёт?
Пока сам не сделаешь...
Re[5]: [Trick] Легальный способ доступа к закрытым членам
От: _NN_ www.nemerleweb.com
Дата: 28.09.18 21:27
Оценка:
Собрав всё воедино получилось вытащить тип и указатель на член наружу.

Получилось вытащить смещение от начала класса, что в принципе должно быть достаточно, чтобы получить доступ.
Осталось понять получить всё во времени компиляции.

Собралось на MSVC.
С GCC надо разбираться
https://ideone.com/nC7H21

Вот набросок.
В Registrator<A>::offset у нас есь смещение A::value.

Буду рад дальнейшим идеям.

#include <iostream>

struct A
{
public:

    int GetValue() const { return value; }

private:
    int q[100];

    int value = -1;
};

template<class MemberPtr, MemberPtr Mem>
struct MemberTag;


template<typename T>
struct MemberOffset
{
    static intptr_t offset;
};

template<typename T>
intptr_t MemberOffset<T>::offset;


template<typename T>
struct Registrator
{
    template<class PointerToMemberType, PointerToMemberType Member>
    struct RegistratorInner
    {
        using TheType = PointerToMemberType;
        static constexpr TheType TheMember = Member;

        struct OffsetInitializer
        {
            OffsetInitializer()
            {
                // Hack to get runtime value of pointer-to-member
                union PtrUnion
                {
                    PointerToMemberType m;
                    intptr_t i;
                };


                PtrUnion p;
                p.m = Member;

                MemberOffset<T>::offset = p.i;
            }
        };

        static OffsetInitializer offsetInitializer;
    };
};


template<typename T>
template<class PointerToMemberType, PointerToMemberType Member>
typename Registrator<T>::template RegistratorInner<PointerToMemberType, Member>::OffsetInitializer
    Registrator<T>::RegistratorInner<PointerToMemberType, Member>::offsetInitializer;


template<class T>
struct MemberExtractor {};

// Extractor specialization
template<class PointerToMemberType, PointerToMemberType Member>
struct MemberExtractor<MemberTag<PointerToMemberType, Member>>
{
    using TheType = PointerToMemberType;
    static constexpr TheType TheMember = Member;
};

// Private member specialization
template<>
struct MemberTag<decltype(&A::value), &A::value>
{
    using TheType = typename MemberExtractor<MemberTag>::TheType;
    static constexpr TheType TheMember = MemberExtractor<MemberTag>::TheMember;

    // Extract type
    virtual typename Registrator<A>::RegistratorInner<TheType, TheMember>::OffsetInitializer F()
    {
        return Registrator<A>::RegistratorInner<TheType, TheMember>::offsetInitializer;
    }
};

template<>
struct MemberTag<decltype(&A::value), &A::value>;

int main()
{
    std::cout << MemberOffset<A>::offset; // 400
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: [Trick] Легальный способ доступа к закрытым членам
От: rg45 СССР  
Дата: 29.09.18 08:15
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Собрав всё воедино получилось вытащить тип и указатель на член наружу.


_NN>Получилось вытащить смещение от начала класса, что в принципе должно быть достаточно, чтобы получить доступ.

_NN>Осталось понять получить всё во времени компиляции.

Ну так пока что только смещение и удалось вытащить, ну а что дальше? Чтобы получить-таки доступ к члену, придется использовать принудительное преобразование к нужному типу, который указывать, опять же, придется вручную. Ведь decltype(&A::value) здесь снова не прокатит. Или я чего-то не понял?
--
Re[7]: [Trick] Легальный способ доступа к закрытым членам
От: _NN_ www.nemerleweb.com
Дата: 29.09.18 08:23
Оценка:
Здравствуйте, rg45, Вы писали:

R>Ну так пока что только смещение и удалось вытащить, ну а что дальше? Чтобы получить-таки доступ к члену, придется использовать принудительное преобразование к нужному типу, который указывать, опять же, придется вручную. Ведь decltype(&A::value) здесь снова не прокатит. Или я чего-то не понял?


Что-то я поспешил. Надо думать.
Кстати код собирается в GCC , не хватало --std==c++17.
https://coliru.stacked-crooked.com/a/facb672f1ff2cd5a
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Восстановил (msvc only)
От: _NN_ www.nemerleweb.com
Дата: 29.09.18 16:37
Оценка:
Здравствуйте, rg45, Вы писали:

Возможно можно обыграть такую инъекцию дружественной функции.

http://coliru.stacked-crooked.com/view?id=24844806b98f3a0aa2a2be755bade6be-f674c1a6d04c632b71a62362c0ccfc51
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.