?

Log in

No account? Create an account
C++ (программистское) - Поклонник деепричастий [entries|archive|friends|userinfo]
Anatoly Vorobey

[ website | Website ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Links
[Links:| English-language weblog ]

C++ (программистское) [мар. 15, 2004|10:21 pm]
Anatoly Vorobey
Проверьте себя: сумеете ли вы правильно ответить, не запуская, что должна напечатать эта программа:

    #include <iostream>
    #include <complex>
    using namespace std;

    class Base {
    public:
        virtual void f( int ) {
            cout << "Base::f(int)" << endl;
        }

        virtual void f( double ) {
            cout << "Base::f(double)" << endl;
        }

        virtual void g( int i = 10 ) {
            cout << i << endl;
        }
    };

    class Derived: public Base {
    public:
        void f( complex<double> ) {
            cout << "Derived::f(complex)" << endl;
        }

        void g( int i = 20 ) {
            cout << "Derived::g() " << i << endl;
        }
    };

    void main() {
        Base    b;
        Derived d;
        Base*   pb = new Derived;

        b.f(1.0);
        d.f(1.0);
        pb->f(1.0);

        b.g();
        d.g();
        pb->g();

        delete pb;
    }



Я вот не смог, ошибся в одном месте. Значит ли это, что я не помню C++? Наверняка. Я много лет не писал на нём (в отличие от C, на котором пишу время от времени). Но знаете что? я пока не соскучился.

Нафиг, нафиг. Java, C#, да что угодно пусть придёт, но от этого плюсплюсного конгломерата сложных и плохо продуманных синтаксических сталагмитов пора избавляться.

Хотите ещё один курьёз? Пожалуйста. Вот такой код:

#include <iostream>
#include <complex>
using namespace std;
                                                                                
int main() {
  int x=1, y=1;
  for( int i = 0; i < 100; ++i ) {
    ++y;
    // What will the next line do? Increment???????????/
    ++x;
  }
  cout << "x=" << x << " y=" << y <<endl;
  return 0;
}

что напечатает?

Думаете, "x=101 y=101"? А вот и нет. Он напечатает "x=1 y=101". Угадайте почему.

Когда кто-то писал комментарий, в конце строки вопросительных знаков случайно отпустил shift, и получил слэш. А ??/ — это триграф, обозначающий бэкслэш, т.е. \, и этот \ съедает следующий за ним \n, и делает строку ++x; частью комментария.

Про триграфы можно прочитать здесь. Там же про диграфы есть. Вы знаете, что в C++ можно использовать "and" и "or" вместо && и ||? Я не знал.


Да, кстати, правильные ответы и объяснения по поводу первого куска кода есть здесь. Там же есть ещё много сложных вопросов и мини-статей по синтаксису и возможностям C++.
СсылкаОтветить

Comments:
Страница 1 из 2
<<[1] [2] >>
[User Picture]From: cema
2004-03-15 12:25 pm
Да вообще-то. Да.
(Ответить) (Thread)
[User Picture]From: anton
2004-03-15 12:46 pm
Нафиг, нафиг. Java, C#, да что угодно пусть придёт, но от этого плюсплюсного конгломерата сложных и плохо продуманных синтаксических сталагмитов пора избавляться.

В C# и Java, не думая, тоже можно много чего наворотить.
А ничего подобного тому, что сейчас можно делать на C++ вообще, не говоря уж об элегантности нового кода и производительности, сделать на них просто нельзя.

По крайней мере, до нормального появления в них шаблонов, да и дальше, я так чувствую -- они заметно хуже продуманы, мне кажется.
(Ответить) (Thread)
[User Picture]From: anton
2004-03-15 12:48 pm
Ваша ссылка на gotw напомнила мне вашу же недавнюю запись про ссылку на Гугл :)
(Ответить) (Parent) (Thread)
[User Picture]From: tejblum
2004-03-15 12:57 pm
Второй курьёз, кстати, отлично работает и в C.
(Ответить) (Thread)
[User Picture]From: yigal_s
2004-03-15 01:04 pm
Я не специалист по столь тонким вопросам, да и на С давно не пишу, но, кажется, в ISO C99 есть ровно такой же набор ди/триграфов, что и в С++.

Что до 1-го примера, то было бы интересно услышать, как должен выглядеть язык, в котором пример, подобный приведенному, не вызовет проблем с пониманием у человека, слегка подзабывшего "закоулки".

Или, переиначивая вопрос, скажем, почему проблемы, подобные приведенным в первом примере, не возникают в тех же C# или Java?
(Ответить) (Thread)
From: oblomov_jerusal
2004-03-15 01:19 pm
По-моему, триграфы тянутся в C с каких-то незапамятных времен.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: evolver
2004-03-15 01:18 pm
Думаете, "x=101 y=101"? А вот и нет. Он напечатает "x=1 y=101". Угадайте почему.

С gcc 2.95.3 фокус не прошел. Сказало "x=101, y=101". В исходнике последовательность пердставлена как "3f 3f 3f 2f 0a 20 20", т.е. вроде бы все с начальным условием задачи совпадает.
(Ответить) (Thread)
From: drw
2004-03-15 01:41 pm
В 3.2 то же.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: ostap
2004-03-15 01:27 pm
Это всё было заложено уже в С. С++ - прямое продолжение сишной идеологии.
Что вообще хорошего можно сказать про язык, в котором обычная переменная по умолчанию передаётся по значению, а массив - по адресы, и более того, где массив вообще, не изъёбываясь специально, нельзя передать по значению, а только по адресу и можно. Прямая дорога к отладочному аду. Мне кажется, одного этого достаточно, чтобы с ним не связываться, если есть хоть малейшая возможность.
(Ответить) (Thread)
[User Picture]From: ifyr
2004-03-15 01:55 pm
> Что вообще хорошего можно сказать про язык, в котором обычная переменная по умолчанию передаётся по значению, а массив - по адресу

Так массив же -- это просто указатель, так что здесь все логично. Хотите семантику по значению -- std::vector к вашим услугам.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: ydolgov
2004-03-15 01:30 pm
По-моему, в мире есть только два языка от Бога: C и Common Lisp (я рассматриваю Scheme как разновидность Lisp). Всё остальное, естественно, от Лукавого.

К слову сказать, для обектно-ориентированного программированя простой C подходит гораздо больше, чем C++.

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

Я не понимаю, почему люди почти всегда игнорируют простое и красивое, а выбирают для пользования всякую дрянь. Ведь это не только в программировании, это, похоже, во всём...
(Ответить) (Thread)
[User Picture]From: zigmar
2004-03-15 01:58 pm
> для обектно-ориентированного программированя простой C подходит гораздо больше, чем C++
И как на с полиморфизм писать? Запонять в ручную vtables как в GTK? Нет уж, спасибо...

Насчет языков програмирования - нету языков универсальный и идеальных. Каждой задаче - свои языки.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: ifyr
2004-03-15 01:58 pm
C++ -- язык с четко определенной внутренней логикой, и зная эту логику в подобные ловушки не попадаешь. Да, C# и Java проще, но C++ предоставляет намного больше возможностей, и многие вещи в нем делаются намного проще (libraries aside) учитывая наличие шаблонов и множественного наследования.
(Ответить) (Thread)
[User Picture]From: avva
2004-03-15 02:14 pm
На деле люди не попадают в ловушки потому, что выбирают для себя какое-то подмножество C++, и по сути дела пишут в нём. Очень редко кто использует весь конгломерат возможностей языка. А в большом проекте это вообще гарантирует фиаско.

Слишком bloated язык получился. Ну уж очень.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: _under_score_
2004-03-15 02:18 pm
а ошиблись, наверное, во второй строке.

действительно: то, что компилятор сначала попытается откастить вызов для всех возможных оверлоадов наследника, и лишь потом перейдет к родителю - не самый известный факт. кстати, кто может тыкнуть на соответствующее место в ISO?
(Ответить) (Thread)
[User Picture]From: avva
2004-03-15 02:48 pm
На самом деле нет: компилятор вообще не будет пытаться переходить к родителю в данном случае, потому что определение f в наследнике скрыло f(double) в родителе. Кажется, это называется hide-by-name semantics. Если бы у complex не было конструктора из double, то компилятор должен был бы ошибку выдать.

Ошибся я в последней строке, т.к. не помнил, что дифолтные значения берутся из базового класса, даже если вызывается виртуальная функция наследника. На самом деле это просто, если подумать немного (ясно же, что это во время компиляции происходит), но я не подумал ;)
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: a_konst
2004-03-15 02:22 pm
никто еще не похвастался что правильно предсказал вывод первого упражнения :)
значит я похвастаюсь :)

а вот со вторым у меня сперва не вышло -- точнее, напечаталось "101, 101."
и только --ansi смог заставить g++ получить описанный результат.
(Ответить) (Thread)
From: (Anonymous)
2004-03-15 03:37 pm
> ... от этого плюсплюсного конгломерата сложных и плохо
> продуманных синтаксических сталагмитов пора избавляться

Забавно, как даже такие казалось бы нетривиальные люди как avva так банально реагируют на непонимание - "избавляться". Не нравится язык - не используй. Нет, нужно от него "избавляться"!
(Ответить) (Thread)
[User Picture]From: ostap
2004-03-15 03:41 pm
Not so easy, учитывая, что это самый распространённый из ООП языков. Вот все вроде бы согласны, что пора избавляться от Windows, включая даже американское правительство. А поди ж ты.
(Ответить) (Parent) (Thread) (Развернуть)
OT - (Анонимно) Развернуть
From: ex_egle611
2004-03-15 10:38 pm
А ответы на задачки давать не принято? А то первый пример меня очень интересует, и объяснение.
(Ответить) (Thread)
[User Picture]From: avva
2004-03-15 10:43 pm
Есть ссылка в самом конце записи (первая ссылка в последнем абзаце) на ответ и объяснение.
(Ответить) (Parent) (Thread) (Развернуть)
[User Picture]From: muchacho
2004-03-15 11:49 pm
Во втором примере микрософтовский компилятор даёт предупреждение.

У C++ есть неоспоримое преимущество: с ним не соскучишься.
(Ответить) (Thread)
[User Picture]From: shtraz
2004-03-16 12:37 am

Даешь голосование!

Авва, Вам надо было просто организовать голосование: кто за, кто против, кто воздержался.

Вчера, как только прочитал эту Вашу запись, я подумал, ну кто я такой, чтобы защищать С++, он и без меня справится. Выгораживать его не хочу. Однако, прочитав тред, свою долю флуда на эту тему непримену добавить:

1. Несмотря на то что C# мне очень по душе, до С++ ему еще надо подрасти: template'ы - грандиозная вещь, одни они чего стоят!
2. Эта уйма возможностей, тонкости, неожиданные аспекты - это-то как раз и обеспечивает его мощь и красоту.

А касательно вопросов: и триграфы/диграфы, и "and/or" введены не просто так, т.е. в тех языках где их нет, либо должно быть что-то другое, эквивалентное, либо не будем сравнивать их с С++.
И три/диграфы, и "and/or/xor/bitand/..." описаны у Срауструпа в 3 издании в приложении В "Технические подробности". Страус у многих программирующих на С++ всегда под рукой.
(Ответить) (Thread)
From: ex_matiouch
2004-03-16 01:55 am

а известно ли благородному дону, что

int i = 1;
i += ++i + i++;
cout << i;

— даёт разные результаты в MS C++, g++ и SUN Java. Сиречь, буквально три различных результата.
(Ответить) (Thread)
[User Picture]From: kukutz
2004-03-16 07:41 am

Re: а известно ли благородному дону, что

В php4.3.3 - семь =)
(Ответить) (Parent) (Thread) (Развернуть)
Страница 1 из 2
<<[1] [2] >>