gcc не компилирует override
struct override {};
struct A {
virtual override override() = 0;
};
struct B : A {
auto override() -> struct override override{
return ::override{};
}
};
int main() {
B().override();
}
Почему clang компилирует без проблем, а gcc - нет? Кто прав и почему?
error: declaration of 'virtual override A::override()' changes meaning of 'override'
Также интересно, нужен ли :: и почему. Никто не хочет компилировать без него.
error: reference to non-static member function must be called; did you mean to call it with no arguments?
Ответы (1 шт):
Это код с собеседования? Не стоит использовать полуключевое слово (override) как имя функции и имя структуры одновременно. Ни к чему хорошему это не приведет. В данном случае компилятор gcc об этом явно и предупреждает. Но если очень-очень хочется выстрелить себе в ногу в будущем, то пока можно это спрятать, явно подсказав компилятору, что там именно такое
struct A {
virtual struct override override() = 0;
};
Но не пишите такое в продакшн код и не показывайте на собеседованиях.
Но на самом деле здесь ошибка просто мастерски спрятана (если бы меня таким кодом собеседовали, я бы встал и вышел (и я так делал, очень рекомендую!)). Можно смело override заменить на test и будет такая же ошибка.
Есть такая цитата в стандарте [3.3.7 Class Scope]
A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.
Если кратко - одно и тоже имя в пределах класса должно значить одно и тоже. Но от компилятора не требуется диагностика.
Поэтому gcc прав, он знает, что программа плохая и говорит об этом (хотя и не должен был этого делать).
clang не говорит о том, что программа плохая (но и не должен был), но при этом скомпилировал программу.
двойное двоеточие в return ::override{}; нужно, что бы компилятор догадался, что здесь именно внешнее имя, а не имя функции или ещё что то.