GCC разрешает доступ к приватному статическому члену - PullRequest
0 голосов
/ 28 мая 2018

Этот код работает на GCC, но не на лягушке.

class Base
{
    static constexpr int PRIVATE = 1;
};

struct Derived : public Base
{
    template <class T>
    int bar( T & t )
    {
        return PRIVATE;
    }
};

int main()
{
    Derived d;
    int i = 3;
    d.bar(i);
}

Ссылка Godbolt: https://godbolt.org/g/qPJ47p

В случае закрытой функции-члена GCC правильно обнаруживает попытку доступа кзакрытый член, если функция шаблона создана, но в противном случае - нет.Clang обнаруживает попытку, даже когда функция шаблона никогда не создается.

Однако, при использовании частной статической переменной constexpr, GCC (до последней версии 8.1) не может остановить частный доступ, даже если функция шаблона создана.Clang правильно (?) Жалуется.

Вопрос: какой из двух компиляторов соответствует стандарту в этой ситуации?

Мне кажется, что GCC не может быть прав, предоставляя доступ кчастная статическая переменная constexpr.Тем не менее, в то же время это не кажется слишком сложной проблемой, но не в последней версии GCC: это делает его преднамеренным.

Большое спасибо paxdiablo за егочеткий и исчерпывающий ответ.В соответствии с его предложением я составил более полный список тестовых примеров и сузил его до спецификатора static, вызывающего проблему для GCC.См. Эту ссылку Godbolt для более подробной информации: https://godbolt.org/g/A3zCLk

Comparison of GCC and Clang:

Private member    | GCC         | Clang

static const      | accept      | reject
static constexpr  | accept      | reject
static            | accept      | reject
const             | instantiate | reject
no-specifiers     | instantiate | reject
static function   | instantiate | reject
function          | instantiate | reject

("instantiate" means GCC rejects it upon template instantiation)

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

извиняюсь, это не ответ, а, возможно, связанная с этим проблема:

//g++ 4.8.4 compiles, g++ 5.4 fix it so it correctly fails to compile.
template<size_t N>
class T{
  public:
    constexpr static size_t m = N;
};

class A{
  constexpr static int a = 10;
};

namespace{
  auto t = T<A::a>::m;
}

int main(){
  cout <<  t << endl;
  return 0;
}

Я еще не нашел номер ошибки.

0 голосов
/ 28 мая 2018

Это определенно выглядит как ошибка, поскольку независимо от того, является ли это экземпляром шаблонной функции или реальной функцией, она не должна иметь никакого отношения к доступности закрытых членов в базовом классе.Если вы измените свой код на:

int bar(int&) {
    return PRIVATE;
}

, то он справедливо пожалуется:

testprog.cpp: In member function 'int Derived::bar(int&)':
testprog.cpp:3:26: error: 'constexpr const int Base::PRIVATE' is private
     static constexpr int PRIVATE = 1;
                          ^
testprog.cpp:9:16: error: within this context
         return PRIVATE;
                ^

Я бы просто поднял это как ошибку на gcc.Если они do по-разному оценивают его действительность, они сообщат вам об этом.

И, когда вы do сообщите об ошибке, я быпредложите использовать абсолютный минималистский пример, который работает, им будет намного легче отлаживать.Я получил это до:

class Base {
    static constexpr int PRIVATE = 42;
};
struct Derived : public Base {
    template <class T> int bar(T) {
        return PRIVATE;
    }
};
int main() {
    Derived d;
    return d.bar(1);
}

Вы также можете указать различные возможности объявления PRIVATE и их влияние на gcc и clang (стволы на этот вопрос):

                                gcc       clang
                              --------   --------
static constexpr int          accepted   rejected
static const int              accepted   rejected
const int                     rejected   rejected
int                           rejected   rejected

Использование взамен функции без шаблонов (как упомянуто выше):

int bar(int) {
    return PRIVATE;
}

, кажется, приводит к gcc «поведению» себя:

                                gcc       clang
                              --------   --------
static constexpr int          rejected   rejected
static const int              rejected   rejected
const int                     rejected   rejected
int                           rejected   rejected

Так что, если это действительно a gcc проблема, я бы подумал, что есть некоторое взаимодействие между static и шаблонами, которое вызывает проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...