1. C++ / Говнокод #12154

    +23

    1. 1
    2. 2
    typedef const AbstractParameter ConstAbstractParameter;
    class Parameter: public ConstAbstractParameter{

    GCC это не компилирует, но в 2008 ms vs компилируется без предупреждений. Я это как увидел, так сразу переписал на

    class Parameter: public AbstractParameter{

    А вот теперь я дома и не могу заснуть. Гложет чувство, что я поступил не правильно. Такое чувство как-будто этот const, пусть и не в рамках стандарта С++, но что-то он делал.

    Запостил: LispGovno, 20 Ноября 2012

    Комментарии (24) RSS

    • Как-то у меня начала пропадать вера в говно. Даже нет желания постить ни на каких языках... Кризис веры...
      Ответить
      • Ну давай проанализируем ситуацию - константное наследование, это чтото новенькое. Возможно проблема в тайпдефе и GCC не хочет наследовать от маски (cl охотно это деляет).
        Ответить
        • >Ну давай проанализируем ситуацию
          И каковы результаты анализа?
          Казнить нельзя помиловать.
          Ответить
    • g++ 4.7 компилирует o_O
      Ответить
      • То есть это в рамках стандарта? И какими же свойствами они наделили объект, в одном из предков которого есть константный объект?
        typedef int CInt;
        Там случно не разрешили наследоваться от CInt? Зачем останавливаться на пол пути.
        Ответить
      • И что самое забавное, вот в том коде: http://pastebin.com/WL16Nw2w

        b.baz() вызывается без вопросов.
        Ответить
        • Похоже const игнорируется и это очередная бесполезная фича.
          Ответить
          • По всему видно, крестосоздатели заскучали. Решили развлечься и добавили новую крестовозможность. Теперь можно крестококохвалиться перед поссанами во дворе.
            Ответить
      • -Wall и -Pedarastic -Pedantic пробовал?
        Ответить
        • Так изначально и делал. Молчит, фраер.
          Ответить
          • А так?
            class Parameter: public const AbstractParameter{
            А если в тайпдеф volatile вместо const пихнуть?
            Ответить
            • class Parameter: public const ConstAbstractParameter {


              Fail.

              typedef const volatile AbstractParameter ConstAbstractParameter;
              class Parameter: public AbstractParameter {


              Ok.
              Ответить
              • > typedef const volatile AbstractParameter ConstAbstractParameter;
                > class Parameter: public AbstractParameter {
                Fail.
                Ответить
                • Очепятка :(
                  Ответить
                  • То есть везде до этого код в g++ не компилировался, а это была лишь опечатка?
                    Ответить
                    • Именно. Просто копипастилговнокодил пример с топика. У меня такой код:
                      #include <iostream>
                      using namespace std;
                      
                      class A {
                      public:
                          int foo() { return 42; }
                      };
                      
                      typedef const volatile A ConstA;
                      
                      class B : public ConstA {};
                      
                      int main() {
                          B b;
                      
                          cout << b.foo() << endl;
                      
                          return 0;
                      }
                      Ответить
                    • > То есть везде до этого код в g++ не компилировался

                      Компилировался.
                      Ответить
                      • Алё гоп!
                        typedef class {
                        public:
                            void foo() const {}
                            void baz() {}
                        } const A;
                         
                        class B : public A {
                           void nineTailedFox() {}
                           void silentHill() const {}
                        };
                         
                        int main() {
                            B b;
                            A& a=b;
                            b.foo();
                            b.baz();
                            a.foo();
                            //a.baz(); //Ошибка компиляции. 
                            return 0;
                        }
                        Вот лошадка и п рыгнула.
                        И так новое свойства такого класса с наследованием от константного класса:
                        При вызове метода через предка - можно вызывать только константные методы, зато через потомка это ограничение уже не влияет.

                        g++ подтверждает?
                        Ответить
                        • Шайтан. Подтверждает.
                          Ответить
                        • .
                          Ответить
                        • Наследование тут не при чём абсолютно:

                          typedef const class {
                            public:
                              void a() {}
                              void b() const {}
                          } A;
                          
                          int main() {
                            A a;
                            // a.a(); // ошибка
                            a.b();
                            return 0;
                          }


                          g++ -Wall -pedantic
                          Ответить
    • class X: mutable Y {};
      Ответить
      • Только не говори, что код выше компилируется?
        class T: public class {/*я анонимный класс*/}
        {
        };
        Ответить
    • Из бактрекера гцц: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48798.

      В стандарте с++98 написано: A typedef name (7.1.3) that names a class is a class-name. Про cv ничего не написано.

      А вот в с++11 есть такой пункт: "If a typedef-name that names a cv-qualified class type is used where a class-name is required, the cv-qualifiers are ignored."
      Ответить

    Добавить комментарий