Является ли эта проблема gcc 12.1 const ошибкой или функцией: попытки вызвать неконстантную функцию с константным объектом

Мы видим, что код C++, который успешно компилируется в gcc 11.3, и Visual Studio 2022 имеют проблемы с gcc 12.1. Код в Godbolt: https://godbolt.org/z/6PYEcsd1h (Спасибо @NathanPierson за его упрощение.)

По сути, класс шаблона решает попытаться вызвать неконстантную функцию базового класса в константной функции, даже если доступна константная перегрузка. Похоже, это какая-то ошибка компилятора, но это может быть какое-то странное новое правило C++, которое я не понимаю. Кто-нибудь знает, представляет ли это ошибку компилятора?

struct BaseClass
{
    // Commenting this non-const function out will also fix the compilation.
    int* baseDevice() { return nullptr; }
    const int* baseDevice() const { return nullptr; }
};

template <class ObjectClass>
struct DerivedClass : BaseClass
{

};

template <class ObjectClass>
struct TopClass : DerivedClass<ObjectClass>
{
  public:
    virtual int failsToCompile() const
    {
      // This should choose to call the const function, but it tries to call the non-const version.
      if (BaseClass::baseDevice())
         return 4;

      return 1;
    }
};

int main()
{
    TopClass<int> x;
}
<source>: In instantiation of 'int TopClass<ObjectClass>::failsToCompile() const [with ObjectClass = ConcreteObject]':
<source>:27:17:   required from here
<source>:30:32: error: passing 'const TopClass<ConcreteObject>' as 'this' argument discards qualifiers [-fpermissive]
   30 |       if (BaseClass::baseDevice())
      |           ~~~~~~~~~~~~~~~~~~~~~^~
<source>:14:15: note:   in call to 'MyDevice* BaseClass::baseDevice()'
   14 |     MyDevice* baseDevice() { return nullptr; }
      |               ^~~~~~~~~~
ASM generation compiler returned: 1

Вам нужно объявить саму функцию как const. Так было всегда.

Mark Ransom 17.05.2022 22:22

@MarkRansom Не так ли? const MyDevice* baseDevice() const { return nullptr; }

NathanOliver 17.05.2022 22:23

Это делает выглядит подозрительно. Обходные пути: this->baseDevice() или DerivedClass<ObjectClass>::baseDevice()

Ted Lyngmo 17.05.2022 22:23

@TedLyngmo Спасибо за совет!

Rob L 17.05.2022 22:26

Сделал пример немного более минимальный, много иерархии классов не нужно, чтобы воспроизвести это. Мне нужны BaseClass и DerivedClass, и я не могу просто поместить методы в DerivedClass. Любопытный.

Nathan Pierson 17.05.2022 22:27

Спасибо Натан. Я пытался удалить некоторые вещи, но потом это сработало... :)

Rob L 17.05.2022 23:11

Поздравляю Роб! Обнаружение ошибки компилятора — это перо в шапке! (И спасибо Теду за сообщение об ошибке!)

Eljay 17.05.2022 23:19

У нас есть кодовая база в 10 000 000 строк для нашего проекта, так что это немного упрощает задачу. ;)

Rob L 17.05.2022 23:20

@RobL Это все? :)

Paul Sanders 18.05.2022 00:10
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
8
9
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Is this gcc 12.1 const problem a bug or feature

Это ошибка. Я подал сообщение об ошибке, и уже подтверждено, что проблема исходит от этот коммит.

Заявка была назначена, и разрешение имеет целевую веху версии 12.2, поэтому мы можем надеяться на быстрое исправление.

Другие вопросы по теме