По умолчанию указатель на член const указывает на int? - PullRequest
4 голосов
/ 10 июня 2019

Во время игры с указателями на участника я столкнулся с поведением, которое кажется мне немного противоречивым и несколько противоречивым.Рассмотрим следующую фиктивную структуру:

struct foo {
    int x;
    double d;
};

и следующие main():

int main() {
    int foo::* ptr = &foo::x;
    double foo::* ptr2 = &foo::d;
}

Здесь у нас нет ничего необычного - два указателя на const членов.Код компилируется нормально.

Что привлекло мое внимание, так это то, что когда мы добавляем const, ситуация немного меняется.Рассмотрим следующий код:

int main() {
    // no int or double after const
    const foo::* ptr = &foo::x;
}

Код прекрасно компилируется на GCC 8.2.0 1 .Обратите внимание, что я не указал, к какому типу данных будет обращаться указатель.

Однако этот код:

int main() {
    // notice the only change - "d" instead of "x"
    const foo::* ptr = &foo::d;
}

не компилируется со следующей ошибкой:

ошибка: невозможно преобразовать 'double foo::*' в 'const int foo::*' при инициализации const foo::* ptr = &foo::d;

Что интересно - это предполагает, что по умолчанию указатель const указывает наЧлен косвенно объявлен, чтобы указать на некоторый int член.Это правильное, стандартное поведение?

Стоит отметить, что если мы отбрасываем const, обе эти строки выдают ошибки:

int main() {
    foo::* ptr1 = &foo::x;
    foo::* ptr2 = &foo::d;
}

в виде:

ошибка: ожидаемый неквалифицированный идентификатор перед маркером '*'

ошибка: 'ptr1' |'ptr2' не было объявлено в этой области

Таким образом, вопрос - указывает ли стандарт, что const указатель на член неявно указывает на int, если мы делаемне указано иное, или это нестандартное поведение? (либо расширение GCC, либо ошибка GCC).


1 РЕДАКТИРОВАТЬ: я использую GCC от MinGW- это конкретная сборка.

Ответы [ 2 ]

2 голосов
/ 11 июня 2019

Код является неправильным в ISO C ++, но поведение "implicit int" включено с помощью -fms-extensions, который gcc включает автоматически для нацеливания на Microsoft ABI.

Вы можете отключить егос -fno-ms-extensions.


Я проверил исходный код (gcc-9.1.0 / gcc / cp / decl.c), оказалось, что в режиме ms-extensions предупреждение для неявный int отключен - все, что сгенерировало бы сообщение ISO C++ forbids declaration of %qs with no type, фактически допускается, для типа используется int.

Это, вероятно, больший молот, чем необходимо было решитьлюбую проблему, которую он пытался решить.Вы также можете увидеть расхождение с const *x; или const f();, например.

Я попытался добавить -fno-ms-extensions в сборку для некоторых из моих "больших" проектов Windows, для которых я использую mingw-w64, и получилбез ошибок, так что, возможно, было бы неплохо установить этот флаг по привычке (или даже отправить патч для mingw-w64, чтобы он был отключен по умолчанию ...).

1 голос
/ 10 июня 2019

Итак, вопрос в том, указывает ли стандарт, что указатель на член const неявно указывает на int, если мы не указываем иначе

Нет. GCC обычно дает вам ответ на простом английском языке и отказывается компилировать (или выдает предупреждение, если вы используете -fpermissive):

error: ISO C++ forbids declaration of 'ptr' with no type

Это не расширение. Это разрешено в режиме -fpermissive для сохранения возможности компиляции старого кода.

Похоже, что GCC, поставляемый MinGW-w64, не улавливает эту ошибку. Я не знаю, намеренно это или нет.

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