Интересные обсуждения

темы заинтересовавшие velkin

Тест по C++ для моих студентов

Tilir Tilir
Hi,

В свободное от работы время продолжаю учить детей добру и C++ (с упором на второе).

И вот вчера группа неплохо написала мне простенький midterm тестик на десять вопросов в части которых есть варианты ответа, в части — надо написать пару строчек несложного кода. Условия обычные -- 40 минут и никуда не подглядывать. Но что меня больше всего поразило -- какой фурор этот тест вызвал среди моих коллег, среди которых нашлось даже больше желающих попробовать в нем свои силы, чем среди студентов

Так что решил выложить сюда. Приветствуется конструктивная критика и все такое.

---
With best regards, Konstantin
jazzer
jazzer
13.03.2015 09:48
Здравствуйте, Tilir, Вы писали:

T>Но что меня больше всего поразило -- какой фурор этот тест вызвал среди моих коллег


Ну как может не вызвать фурор тест с "заменить явный шаблонный полиморфизм на CRTP"


Хороший тест, можно на собеседовании давать
kaa.python
kaa.python
13.03.2015 01:37
Здравствуйте, jazzer, Вы писали:

J>Хороший тест, можно на собеседовании давать


На собеседовании на какую позицию? Разработчика компиляторов ну или хотя бы системной библиотеки, аналога stl?
По моему мнению, такой тест имеет чисто академический интерес так как слишком уж слабо коррелирует (еще меньше чем тесты BrainBench) с реальной работой.
jazzer
jazzer
13.03.2015 01:59
Здравствуйте, kaa.python, Вы писали:

KP>Здравствуйте, jazzer, Вы писали:


J>>Хороший тест, можно на собеседовании давать


KP>На собеседовании на какую позицию? Разработчика компиляторов ну или хотя бы системной библиотеки, аналога stl?

ну да, системной библиотеки, на которой потом вся система держаться будет

KP>По моему мнению, такой тест имеет чисто академический интерес так как слишком уж слабо коррелирует (еще меньше чем тесты BrainBench) с реальной работой.

Знание языка — вещь нужная, так как спасает от ошибок и экономит кучу времени на выискивание оных.

Ну и куда ж без CRTP
kaa.python
kaa.python
13.03.2015 02:02
Здравствуйте, jazzer, Вы писали:

J>Знание языка — вещь нужная, так как спасает от ошибок и экономит кучу времени на выискивание оных.


Конечно нужно. Но вот на таком уровне? Очень сомнительно кроме пары крайне редких направлений. Не очень представляю специфику твоей работы, но не думаю что в эти пару направлений попадает, разве что вы нашли фатальный недостаток в STL
jazzer
jazzer
13.03.2015 02:06
Здравствуйте, kaa.python, Вы писали:

KP>Здравствуйте, jazzer, Вы писали:


J>>Знание языка — вещь нужная, так как спасает от ошибок и экономит кучу времени на выискивание оных.


KP>Конечно нужно. Но вот на таком уровне? Очень сомнительно кроме пары крайне редких направлений. Не очень представляю специфику твоей работы, но не думаю что в эти пару направлений попадает, разве что вы нашли фатальный недостаток в STL


Когда начинали — очень даже попадало. Сейчас уже гораздо меньше, конечно — фундамент выстроен, а код, растущий на фундаменте, гораздо проще оного (было бы странно, если бы не). И выстроен без багов, кстати — за эти годы я не не помню ни одного более-менее серьезного бага. И это не в последнюю очередь благодаря тому, что разработчики знали закоулки языка.

ЗЫ Знание закоулков нужно не для того, чтобы их использовать, а в первую очередь — чтобы в них не попадать.
kaa.python
kaa.python
13.03.2015 02:29
Здравствуйте, jazzer, Вы писали:

J>Когда начинали — очень даже попадало. Сейчас уже гораздо меньше, конечно — фундамент выстроен, а код, растущий на фундаменте, гораздо проще оного (было бы странно, если бы не).


Зависит от фундамента. Очень часто такие попадаются, что лучше бы их не было. Особенно если говорить о закрытых, а не OpenSource фундаментах.

J>И выстроен без багов, кстати — за эти годы я не не помню ни одного более-менее серьезного бага.


Это говорит не о качестве фундамента, а о модели разработки либо специфике ПО. Ну либо от того, что ты закладываешь в понятие "серьезного бага".

J>ЗЫ Знание закоулков нужно не для того, чтобы их использовать, а в первую очередь — чтобы в них не попадать.


Зависит от глубины закоулков, если честно. Очень многие из них стоит знать исключительно в академических целях (как, например, обсуждаемый тест).
jazzer
jazzer
13.03.2015 02:46
Здравствуйте, kaa.python, Вы писали:

KP>Зависит от фундамента. Очень часто такие попадаются, что лучше бы их не было. Особенно если говорить о закрытых, а не OpenSource фундаментах.


Ну в нашем случае фундамент что надо. Ибо сами писали под наши задачи, так что не приходится хачить, . Плюс старались делать так, чтоб не возникало монолитного фреймворка (совсем от этого, конечно же, не уйти, и это, наверное, самая трудная задача, но мы старались).

J>>И выстроен без багов, кстати — за эти годы я не не помню ни одного более-менее серьезного бага.

KP>Это говорит не о качестве фундамента, а о модели разработки либо специфике ПО. Ну либо от того, что ты закладываешь в понятие "серьезного бага".

А что должно говорить о качестве ПО, если не отсутствие багов?
Это достаточно важный параметр, на мой взгляд

J>>ЗЫ Знание закоулков нужно не для того, чтобы их использовать, а в первую очередь — чтобы в них не попадать.


KP>Зависит от глубины закоулков, если честно. Очень многие из них стоит знать исключительно в академических целях (как, например, обсуждаемый тест).


Фигня с закоулками состоит в том, что если ты про них не знаешь, то ты пишешь себе код, который выглядит невинно, и ни сном ни духом, что там затаилась какая-нть мерзость.
То есть когда говорят, что знать все не надо, ибо всегда можно нагуглить — чтоб гуглить, надо знать, что гуглить. А если у тебя программа на ровном месте то падает, то не падает — что ты будешь гуглить, чтобы понять, что написал невинно выглядящее UB? А априорное знание позволяет сразу не писать опасный код.
smeeld
smeeld
13.03.2015 02:52
Здравствуйте, jazzer, Вы писали:

J>ЗЫ Знание закоулков нужно не для того, чтобы их использовать, а в первую очередь — чтобы в них не попадать.


Уверены в том, что дыры в прогах от незнания языка?
Самые опасные и известные уязвимости-это особенности архитектуры проги/либы.
А говорящий, с воздетым к небу перстом, про необходимость умения непопадать в ловушки языка-это или клинический идиот
с манией к такому попаданию, или использующий ЯП, который сам по себе есть одно сплошно попадалово. Вот смотрю на эти
С++-вые бороды кончиты, и всё больше удивляюсь тому, как глубоко филигранно продуман Lisp, начиная с самого своего фундамента,
что Lisp придумали именно те, кого нужно и можно подпускать к разработке ЯП, а C++ развивают те, кого к ЯП подпускать категорически
запрещено. ЯП должны развивать математики, а не скинтисты и инженеры, что и наблюдается при сравнении C++ с тем же Lisp.
denisko
denisko
13.03.2015 02:10
Здравствуйте, kaa.python, Вы писали:

KP>На собеседовании на какую позицию? Разработчика компиляторов ну или хотя бы системной библиотеки, аналога stl?

Знаешь к концу обучения на любом программистком факультете со специализацией в C, слово explicit должно быть выбито кровавыми мозолями на заднице студентов. Так что тут все ок.

KP>По моему мнению, такой тест имеет чисто академический интерес так как слишком уж слабо коррелирует (еще меньше чем тесты BrainBench) с реальной работой.

Тут сложно не согласиться, очень однобокий тест.
Dym On
Dym On
13.03.2015 09:57
Спасибо! А еще есть ?
Tilir
Tilir
16.03.2015 10:04
Здравствуйте, Dym On, Вы писали:

DO>Спасибо! А еще есть ?


Я раньше ориентировался в основном на выдачу вычислительно сложных домашних работ. То есть в лоб нерешаемых за разумное время, но даже если придумать неплохой алгоритм, то он должен занимать минимум часок машинного времени на обсчет чтобы был виден эффект от тонких ручных оптимизаций. Ну вроде задачи поиска всех пятерок kissing primes при условии что каждый элемент пятерки <= 100000.

А теперь вот попробовал сделать ещё и тест и мне понравился результат -- многие из группы теперь потратят дополнительное время чтобы разобраться в тонкостях, которые им могли и не встретиться на более практических заданиях.

Так что если ещё что сделаю, выложу, тем более народу тут вроде тоже в целом понравилось.
smeeld
smeeld
16.03.2015 10:23
Здравствуйте, Tilir, Вы писали:

T>А теперь вот попробовал сделать ещё и тест и мне понравился результат -- многие из группы теперь потратят дополнительное время чтобы разобраться в тонкостях, которые им могли и не встретиться на более практических заданиях.


Какое Ваше мнение о том, насколько "наизусть" должен знать стандарт среднестатистический разработчик C++?
И насколько разработчие компилятора?
Tilir
Tilir
16.03.2015 11:11
Здравствуйте, smeeld, Вы писали:

S>Какое Ваше мнение о том, насколько "наизусть" должен знать стандарт среднестатистический разработчик C++?

S>И насколько разработчие компилятора?

Наизусть это лишнее. Знать структуру стандарта, ориентироваться в возможностях языка и иметь интуицию относительно основных решений в дизайне языка -- норм. Период обучения -- прекрасное время выработать эту интуицию разбором всяких интересных частностей.
smeeld
smeeld
16.03.2015 12:07
Здравствуйте, Tilir, Вы писали:

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


Ok. Как тогда Вам покажется вопросик типа

Дано
template<class T1 = float, class T2> class Foo;
В чём ошибка?


Это можно хоть на тестиках хоть на собеседовраниях спрашивать. Сложного ничего, но
подобное именно требует знания стандарта почти наизусть, и если на вопросик правильно не ответит,
то как бы и не знает хорошо C++.
Tilir
Tilir
16.03.2015 03:42
Здравствуйте, smeeld, Вы писали:

Ok. Как тогда Вам покажется вопросик типа

Дано
template<class T1 = float, class T2> class Foo;
В чём ошибка?


Это слишком легкий вопрос. Он был бы сложнее если бы вы спросили "есть ли тут ошибка?".

Я совершенно честно не заглядывая в стандарт сейчас просто привлекаю интуицию и логику: представим что так можно делать. Как могло бы выглядеть инстанцирование с дефолтным первым аргументом?

Foo <int> t; /* T1 = float? */


Это очевидно противоречит базовому правилу языка "как пишется, так и указывается" и главное создает неоднозначности при разборе более слоных смешанных списков:

template<class T1 = float, class T2, class T3 = int> class Bar;
Bar <int, float> t; /* Hm? */


Ещё один вариант как это могло бы выглядеть -- явная запятая:

Foo <,int> t; /* T1 = float! */


Но (это уже интуиция) я не поверю, что такое уродство прошло через комитет.

Значит ошибка в том, что default template parameters могут быть только trailing.
DarkEld3r
DarkEld3r
16.03.2015 03:47
Здравствуйте, Tilir, Вы писали:

T>Значит ошибка в том, что default template parameters могут быть только trailing.

Помимо того, что это логично и вполне интуитивно, добавлю, что с функциями точно так же. А о них узнают задолго до того как начинают в тонкостях шаблонов разбираться и новый опыт не противоречит старому. В общем, вопрос элементарный.
smeeld
smeeld
16.03.2015 04:08
Здравствуйте, Tilir, Вы писали:

T>
T>Foo <int> t; /* T1 = float? */
T>


T>Это очевидно противоречит базовому правилу языка "как пишется, так и указывается" и главное создает неоднозначности при разборе более слоных смешанных списков:


Понятно про нелогичность случая смешанных дефолтов

template <class T1=def2, class T2, class T3=def3, ... class Tn> class Foo;

Но чем не логична такая конструкция

template <class T1=def2, class T2=def2, class T3, ... class Tn> class Foo

при законности которой компилятор ожидал бы в таком случае инстанцирования в виде

Foo<def3, ...defn> f;

по аналогии с случаем когда

template <class T1, class T2, class T3=def3, ... class Tn=def3> class Foo

предпологающем интстанцирование вида

Foo<def1, def2> f;


Почему по стандарту законен только случай

template <class T1, class T2, class T3=def3, ... class Tn=def3> class Foo

?
VTT
VTT
13.03.2015 10:48
Здравствуйте, Tilir, Вы писали:

T>И вот вчера группа неплохо написала мне простенький midterm тестик на десять вопросов в части которых есть варианты ответа, в части — надо написать пару строчек несложного кода. Условия обычные -- 40 минут и никуда не подглядывать. Но что меня больше всего поразило -- какой фурор этот тест вызвал среди моих коллег, среди которых нашлось даже больше желающих попробовать в нем свои силы, чем среди студентов


Хотелось бы отметить три момента:
1) Тесты по большей части написаны в ключе "представьте, что вы компилятор / процессор бла бла бла".
2) Использование идентификаторов из одной буквы или различающихся на одну букву превращает любой тест в тест на внимательность. Вроде как все борются за читабельность и качество кода, а тут студентам сразу дают плохой пример.
3) Тесты на листочках, да еще и "без подглядывания" — это как-то не соответствует реалиям разработки. Тут конечно зависит от условий проведения, но вообще-то я не вижу как в данном тесте использование поисковиков поможет с решением. Если исключить "помощь друга". А вот навык поиска и копания в дебрях с++ очень бы пригодился. Можно было бы даже добавить вопрос на знание стандартов / поиск в исходниках или что-то подобное.

Первый вопрос повеселил, его можно было бы разделить на 4: когда произойдет вариант 1), когда вариант 2) и т.д.
Tilir
Tilir
16.03.2015 09:59
Здравствуйте, VTT, Вы писали:

VTT>1) Тесты по большей части написаны в ключе "представьте, что вы компилятор / процессор бла бла бла".


Да. В знании языка умение "притворится компилятором" и прочитать с листа код, распарсив в нем возможные проблемы is a must.

VTT>2) Использование идентификаторов из одной буквы или различающихся на одну букву превращает любой тест в тест на внимательность. Вроде как все борются за читабельность и качество кода, а тут студентам сразу дают плохой пример.


Хм. Спасибо. Наверное стоит это скорректировать.

VTT>3) Тесты на листочках, да еще и "без подглядывания" — это как-то не соответствует реалиям разработки. Тут конечно зависит от условий проведения, но вообще-то я не вижу как в данном тесте использование поисковиков поможет с решением. Если исключить "помощь друга". А вот навык поиска и копания в дебрях с++ очень бы пригодился. Можно было бы даже добавить вопрос на знание стандартов / поиск в исходниках или что-то подобное.


Я потом отдаю тест на дом как лабораторную для того чтобы можно было покопаться, набрать, исполнить, повертеть в разные стороны и исправить ошибки.
__kot2
__kot2
13.03.2015 01:19
Здравствуйте, Tilir, Вы писали:
T>Так что решил выложить сюда. Приветствуется конструктивная критика и все такое.
по мне он какой-то сложный и запутанный
как тут написали, неприятно притворяться компилятором и внимательно выглядывать какие-то редкоиспользуемые мелочи
-n1l-
-n1l-
13.03.2015 03:35
Спасибо за то, что выложили этот тест тут.
Очень интересный, но, блин, напрягает использование односимвольных переменных.

Кстати насчет того, как скоимпиллирована программа, как-то можно посмотреть, сколько функций нагенерил шаблон?
Tilir
Tilir
16.03.2015 10:08
Здравствуйте, -n1l-, Вы писали:

N>Очень интересный, но, блин, напрягает использование односимвольных переменных.


Да, надо поправить, мне уже указали.

N>Кстати насчет того, как скоимпиллирована программа, как-то можно посмотреть, сколько функций нагенерил шаблон?


В случае gcc -- посмотреть гимпловый дамп. В момент когда программа в SSA, все эффекты от шаблонов C++ уже учтены.
velkin
velkin
13.03.2015 04:25
Здравствуйте, Tilir, Вы писали:

T>В свободное от работы время продолжаю учить детей добру и C++ (с упором на второе).

T>И вот вчера группа неплохо написала мне простенький midterm тестик на десять вопросов в части которых есть варианты ответа, в части — надо написать пару строчек несложного кода. Условия обычные -- 40 минут и никуда не подглядывать. Но что меня больше всего поразило -- какой фурор этот тест вызвал среди моих коллег, среди которых нашлось даже больше желающих попробовать в нем свои силы, чем среди студентов
T>Так что решил выложить сюда. Приветствуется конструктивная критика и все такое.

#include <cassert>  
template <typename T, typename U> bool 
operator == (const T &x, const U &y) 
{ 
  return !(x < y) && !(y < x);  
} 
template <typename T, typename U> bool 
operator != (const T &x, const U &y) 
{ 
  return !(x == y);  
} 
struct Pair  
{ 
  int m_x, m_y; 
  Pair (int x, int y = 0): m_x(x), m_y(y) {}  
};  
bool 
operator < (const Pair &lhs, const Pair &rhs) 
{ 
  return (lhs.m_x < rhs.m_x) || ((lhs.m_x == rhs.m_x) && (lhs.m_y < rhs.m_y)); 
}  
int 
main (void) 
{ 
  Pair a (2);  
  Pair b (2, 1);  
  int c = 2, d = 2; 
  /* 1 */ assert (b != a);  
  /* 2 */ assert (c == d); 
  /* 3 */ assert (a == c); 
  /* 4 */ assert (d == b); 
  return 0; 
}


gcc main.cpp

a.out

a.out: main.cpp:31: int main(): Assertion `d == b' failed.
Аварийный останов (сделан дамп памяти)


Ещё вопросы?

gcc --help

Usage: gcc [options] file...
Options:
...
  -S                       Compile only; do not assemble or link
..


gcc -S main.cpp

    .file    "main.cpp"
    .section    .text._ZN4PairC2Eii,"axG",@progbits,_ZN4PairC5Eii,comdat
    .align 2
    .weak    _ZN4PairC2Eii
    .type    _ZN4PairC2Eii, @function
_ZN4PairC2Eii:
.LFB3:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    movl    8(%ebp), %eax
    movl    12(%ebp), %edx
    movl    %edx, (%eax)
    movl    8(%ebp), %eax
    movl    16(%ebp), %edx
    movl    %edx, 4(%eax)
    popl    %ebp
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE3:
    .size    _ZN4PairC2Eii, .-_ZN4PairC2Eii
    .weak    _ZN4PairC1Eii
    .set    _ZN4PairC1Eii,_ZN4PairC2Eii
    .text
    .globl    _ZltRK4PairS1_
    .type    _ZltRK4PairS1_, @function
_ZltRK4PairS1_:
.LFB5:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    movl    8(%ebp), %eax
    movl    (%eax), %edx
    movl    12(%ebp), %eax
    movl    (%eax), %eax
    cmpl    %eax, %edx
    jl    .L3
    movl    8(%ebp), %eax
    movl    (%eax), %edx
    movl    12(%ebp), %eax
    movl    (%eax), %eax
    cmpl    %eax, %edx
    jne    .L4
    movl    8(%ebp), %eax
    movl    4(%eax), %edx
    movl    12(%ebp), %eax
    movl    4(%eax), %eax
    cmpl    %eax, %edx
    jge    .L4
.L3:
    movl    $1, %eax
    jmp    .L5
.L4:
    movl    $0, %eax
.L5:
    popl    %ebp
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE5:
    .size    _ZltRK4PairS1_, .-_ZltRK4PairS1_
    .section    .rodata
.LC0:
    .string    "main.cpp"
.LC1:
    .string    "b != a"
.LC2:
    .string    "c == d"
.LC3:
    .string    "a == c"
.LC4:
    .string    "d == b"
    .text
    .globl    main
    .type    main, @function
main:
.LFB6:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $48, %esp
    movl    $0, 8(%esp)
    movl    $2, 4(%esp)
    leal    32(%esp), %eax
    movl    %eax, (%esp)
    call    _ZN4PairC1Eii
    movl    $1, 8(%esp)
    movl    $2, 4(%esp)
    leal    40(%esp), %eax
    movl    %eax, (%esp)
    call    _ZN4PairC1Eii
    movl    $2, 24(%esp)
    movl    $2, 28(%esp)
    leal    32(%esp), %eax
    movl    %eax, 4(%esp)
    leal    40(%esp), %eax
    movl    %eax, (%esp)
    call    _ZneI4PairS0_EbRKT_RKT0_
    testb    %al, %al
    jne    .L8
    movl    $_ZZ4mainE19__PRETTY_FUNCTION__, 12(%esp)
    movl    $28, 8(%esp)
    movl    $.LC0, 4(%esp)
    movl    $.LC1, (%esp)
    call    __assert_fail
.L8:
    movl    24(%esp), %edx
    movl    28(%esp), %eax
    cmpl    %eax, %edx
    je    .L9
    movl    $_ZZ4mainE19__PRETTY_FUNCTION__, 12(%esp)
    movl    $29, 8(%esp)
    movl    $.LC0, 4(%esp)
    movl    $.LC2, (%esp)
    call    __assert_fail
.L9:
    leal    24(%esp), %eax
    movl    %eax, 4(%esp)
    leal    32(%esp), %eax
    movl    %eax, (%esp)
    call    _ZeqI4PairiEbRKT_RKT0_
    testb    %al, %al
    jne    .L10
    movl    $_ZZ4mainE19__PRETTY_FUNCTION__, 12(%esp)
    movl    $30, 8(%esp)
    movl    $.LC0, 4(%esp)
    movl    $.LC3, (%esp)
    call    __assert_fail
.L10:
    leal    40(%esp), %eax
    movl    %eax, 4(%esp)
    leal    28(%esp), %eax
    movl    %eax, (%esp)
    call    _ZeqIi4PairEbRKT_RKT0_
    testb    %al, %al
    jne    .L11
    movl    $_ZZ4mainE19__PRETTY_FUNCTION__, 12(%esp)
    movl    $31, 8(%esp)
    movl    $.LC0, 4(%esp)
    movl    $.LC4, (%esp)
    call    __assert_fail
.L11:
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE6:
    .size    main, .-main
    .section    .text._ZneI4PairS0_EbRKT_RKT0_,"axG",@progbits,_ZneI4PairS0_EbRKT_RKT0_,comdat
    .weak    _ZneI4PairS0_EbRKT_RKT0_
    .type    _ZneI4PairS0_EbRKT_RKT0_, @function
_ZneI4PairS0_EbRKT_RKT0_:
.LFB7:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $24, %esp
    movl    12(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZeqI4PairS0_EbRKT_RKT0_
    xorl    $1, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE7:
    .size    _ZneI4PairS0_EbRKT_RKT0_, .-_ZneI4PairS0_EbRKT_RKT0_
    .section    .text._ZeqI4PairiEbRKT_RKT0_,"axG",@progbits,_ZeqI4PairiEbRKT_RKT0_,comdat
    .weak    _ZeqI4PairiEbRKT_RKT0_
    .type    _ZeqI4PairiEbRKT_RKT0_, @function
_ZeqI4PairiEbRKT_RKT0_:
.LFB8:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    pushl    %esi
    pushl    %ebx
    subl    $32, %esp
    .cfi_offset 6, -12
    .cfi_offset 3, -16
    movl    $0, %ebx
    movl    12(%ebp), %eax
    movl    (%eax), %eax
    movl    $0, 8(%esp)
    movl    %eax, 4(%esp)
    leal    -16(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZN4PairC1Eii
    movl    $1, %esi
    leal    -16(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZltRK4PairS1_
    xorl    $1, %eax
    testb    %al, %al
    je    .L16
    movl    12(%ebp), %eax
    movl    (%eax), %eax
    movl    $0, 8(%esp)
    movl    %eax, 4(%esp)
    leal    -24(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZN4PairC1Eii
    movl    $1, %ebx
    movl    8(%ebp), %eax
    movl    %eax, 4(%esp)
    leal    -24(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZltRK4PairS1_
    xorl    $1, %eax
    testb    %al, %al
    je    .L16
    movl    $1, %eax
    jmp    .L17
.L16:
    movl    $0, %eax
.L17:
    testb    %bl, %bl
    movl    %esi, %edx
    testb    %dl, %dl
    addl    $32, %esp
    popl    %ebx
    .cfi_restore 3
    popl    %esi
    .cfi_restore 6
    popl    %ebp
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE8:
    .size    _ZeqI4PairiEbRKT_RKT0_, .-_ZeqI4PairiEbRKT_RKT0_
    .section    .text._ZeqIi4PairEbRKT_RKT0_,"axG",@progbits,_ZeqIi4PairEbRKT_RKT0_,comdat
    .weak    _ZeqIi4PairEbRKT_RKT0_
    .type    _ZeqIi4PairEbRKT_RKT0_, @function
_ZeqIi4PairEbRKT_RKT0_:
.LFB9:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    pushl    %esi
    pushl    %ebx
    subl    $32, %esp
    .cfi_offset 6, -12
    .cfi_offset 3, -16
    movl    $0, %ebx
    movl    8(%ebp), %eax
    movl    (%eax), %eax
    movl    $0, 8(%esp)
    movl    %eax, 4(%esp)
    leal    -16(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZN4PairC1Eii
    movl    $1, %esi
    movl    12(%ebp), %eax
    movl    %eax, 4(%esp)
    leal    -16(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZltRK4PairS1_
    xorl    $1, %eax
    testb    %al, %al
    je    .L22
    movl    8(%ebp), %eax
    movl    (%eax), %eax
    movl    $0, 8(%esp)
    movl    %eax, 4(%esp)
    leal    -24(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZN4PairC1Eii
    movl    $1, %ebx
    leal    -24(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    12(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZltRK4PairS1_
    xorl    $1, %eax
    testb    %al, %al
    je    .L22
    movl    $1, %eax
    jmp    .L23
.L22:
    movl    $0, %eax
.L23:
    testb    %bl, %bl
    movl    %esi, %edx
    testb    %dl, %dl
    addl    $32, %esp
    popl    %ebx
    .cfi_restore 3
    popl    %esi
    .cfi_restore 6
    popl    %ebp
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE9:
    .size    _ZeqIi4PairEbRKT_RKT0_, .-_ZeqIi4PairEbRKT_RKT0_
    .section    .text._ZeqI4PairS0_EbRKT_RKT0_,"axG",@progbits,_ZeqI4PairS0_EbRKT_RKT0_,comdat
    .weak    _ZeqI4PairS0_EbRKT_RKT0_
    .type    _ZeqI4PairS0_EbRKT_RKT0_, @function
_ZeqI4PairS0_EbRKT_RKT0_:
.LFB10:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $8, %esp
    movl    12(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZltRK4PairS1_
    xorl    $1, %eax
    testb    %al, %al
    je    .L28
    movl    8(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    12(%ebp), %eax
    movl    %eax, (%esp)
    call    _ZltRK4PairS1_
    xorl    $1, %eax
    testb    %al, %al
    je    .L28
    movl    $1, %eax
    jmp    .L29
.L28:
    movl    $0, %eax
.L29:
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE10:
    .size    _ZeqI4PairS0_EbRKT_RKT0_, .-_ZeqI4PairS0_EbRKT_RKT0_
    .section    .rodata
    .type    _ZZ4mainE19__PRETTY_FUNCTION__, @object
    .size    _ZZ4mainE19__PRETTY_FUNCTION__, 11
_ZZ4mainE19__PRETTY_FUNCTION__:
    .string    "int main()"
    .ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    .section    .note.GNU-stack,"",@progbits


Так кто же мы такие и куда движемся. Студенты, коллеги, зачем? Чёрный ящик, игральный автомат, русская рулетка. Почему вас это так заинтересовало. Бред ли? Нет, я компилятор. Понять значит предвидеть. Задумаемся. Пятница, выходной, понедельник. Головоломка. Для чего? Польза, генератор, строка. Дело было вечером, делать было нечего. Галка села на заборе, Кот забрался на чердак. Тут сказал ребятам Боря Просто так. А в-четвертых — наша мама Отправляется в полет, Потому что наша мама Называется — пилот!


А теперь серьёзно, самая неприятная часть С++ это его перегруженность разнообразными правилами. Игра в "Вальяжного профессора" и "Шустрого студента" (для тех кто не понял прочтите документ) не имеет ничего общего с практикой. Составление общей аналитической картины из разрозненных деталей напоминает фразу "опасно быть недоучкой".
Цитирую документ:

3) Я почему-то сейчас понял, что если пять лет писать компиляторы, то сходишь с ума

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

Кто умеет, тот делает. Кто не умеет учит. А кто не умеет даже учить, руководит. Всегда нужно стремиться стать руководителем.
night beast
night beast
13.03.2015 10:46
Здравствуйте, velkin, Вы писали:

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


V>Кто умеет, тот делает. Кто не умеет учит. А кто не умеет даже учить, руководит. Всегда нужно стремиться стать руководителем.


"Хoтелoсь бы, так сказать, в oбщих чертах пoнять, чтo ентому иностранцу нужнo" (с) Иван Васильевич.

расшифруйте для безграмотных, в чем смысл сообщения, то?
velkin
velkin
14.03.2015 12:32
Здравствуйте, night beast, Вы писали:

NB>Здравствуйте, velkin, Вы писали:


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

V>>Кто умеет, тот делает. Кто не умеет учит. А кто не умеет даже учить, руководит. Всегда нужно стремиться стать руководителем.
NB>"Хoтелoсь бы, так сказать, в oбщих чертах пoнять, чтo ентому иностранцу нужнo" (с) Иван Васильевич.
NB>расшифруйте для безграмотных, в чем смысл сообщения, то?

Вот смотрите, все мы люди, хотя, конечно, в интернете никто не узнает, даже если ты кот. Существует две роли, одна может быть от высокоинтелектуальной до самодурской "я начальник" — Вальяжный Учитель, вторая называется "ты дурак" — Шустрый Студент. Это значит буквально следующее, Вальяжный Учитель может придумывать любую теорию, причём я его понимаю, так как в процессе развития сам постоянно так делаю. С другой стороны Шустрый Студент, сокращённо шустрик, в дальнейшем буду звать его шестёркой, должен принимать всё то, что выдумывает Вальяжный Учитель, пусть будет валетом. Причём валет за свои слова и действия не отвечает по определению.

Давайте упростим, предположим валет решил научить шестёрку забивать гвозди. Для начала он попросил шестёрку наклонить гвоздь под углом 30 градусов к поверхности и попробовать его забить. Шестёрка измучился, но забил, естественно коряво. Валет снисходительно поучает, вот видишь шестёрка, так гвозди забивать не желательно. А теперь поставь гвоздь под 90 градусов к поверхности, обхвати его рукой и положи большой палец на шляпку и попробуй забить. Шестёрка всё так и сделал, и закономерно получил травму пальца ещё при первом ударе.

Мне думается лучше один раз показать как правильно забить гвоздь, а потом обучаемый пусть что хочет, то и делает. И второе, давным давно, практически ещё в прошлом тысячелетии мне как и всем остальным выдали задание. Если кратко, то я использовал принцип брутфорс, а вот остальные подобрали значения вручную. Но самое интересное алгоритм показал все значения, вплоть до отрицательных. Грубо говоря у меня было больше результатов, потому что я писал программу, а всю работу сделал компьютер.

Учителя же работают с людьми, и компьютер некоторые из них воспринимают тоже как человека. В отличие от них, я доверяю работу компьютеру и не пытаюсь его переплюнув загрузив себе в мозг знания миллионов инженеров, не говоря уже о скорости вычислений. Все эти листочки с бумажками говорят лишь об одном, Вальяжный Учитель не понимает самой сути компьютерных систем, то есть то, для чего они были созданы. А это уже из разряда психологии. Причём я бы ещё понял, если бы проводились детальные исследования компиляторов, но о об их устройстве ни слова, всё сводится к замене труда компилятора на труд человека.

Есть такой анекдот: "Полиция следит за порядком, беспорядки их не интересуют". Если человек изначально пишет ошибки, чтобы другие догадались, то особого смысла в этом нет. С++ существует для решения задач, но какую задачу решал Вальяжный Учитель? Научиться чему-то можно лишь решая реальные задачи, а не имитируя несуществующие ошибки. Так что в глобальном плане я против такого метода обучения, а шестёрок вообще никто не спрашивал, на то они и шестёрки. С другой стороны прежде чем выбрать стараюсь рассматривать все возможности. Совсем не против почитать доводы в пользу таких тестов, аля забьём гвоздь тысячью и одним неправильным способом.
jazzer
jazzer
14.03.2015 03:18
Здравствуйте, velkin, Вы писали:

V> Если человек изначально пишет ошибки, чтобы другие догадались, то особого смысла в этом нет.


Этот код мог быи написан твоим партнером по команде, и попал к тебе на code review
aik
aik
14.03.2015 12:27
Здравствуйте, jazzer, Вы писали:

V>> Если человек изначально пишет ошибки, чтобы другие догадались, то особого смысла в этом нет.

J>Этот код мог быи написан твоим партнером по команде, и попал к тебе на code review

вот если б я был ревьювером — то конструктор Pair не имел бы "= 0".
night beast
night beast
14.03.2015 07:00
Здравствуйте, velkin, Вы писали:

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

V>>>Кто умеет, тот делает. Кто не умеет учит. А кто не умеет даже учить, руководит. Всегда нужно стремиться стать руководителем.
NB>>"Хoтелoсь бы, так сказать, в oбщих чертах пoнять, чтo ентому иностранцу нужнo" (с) Иван Васильевич.
NB>>расшифруйте для безграмотных, в чем смысл сообщения, то?

V>Вот смотрите, все мы люди, хотя, конечно, в интернете никто не узнает, даже если ты кот. Существует две роли, одна может быть от высокоинтелектуальной до самодурской "я начальник" — Вальяжный Учитель, вторая называется "ты дурак" — Шустрый Студент. Это значит буквально следующее, Вальяжный Учитель может придумывать любую теорию, причём я его понимаю, так как в процессе развития сам постоянно так делаю. С другой стороны Шустрый Студент, сокращённо шустрик, в дальнейшем буду звать его шестёркой, должен принимать всё то, что выдумывает Вальяжный Учитель, пусть будет валетом. Причём валет за свои слова и действия не отвечает по определению.


V>[skip]


фигасе у вас в общих чертах получилось.
если в двух словах, то "тест г-но потому что когда то меня обидел вальяжный учитель"? я ничего не перепутал?

V>Учителя же работают с людьми, и компьютер некоторые из них воспринимают тоже как человека. В отличие от них, я доверяю работу компьютеру и не пытаюсь его переплюнув загрузив себе в мозг знания миллионов инженеров, не говоря уже о скорости вычислений. Все эти листочки с бумажками говорят лишь об одном, Вальяжный Учитель не понимает самой сути компьютерных систем, то есть то, для чего они были созданы. А это уже из разряда психологии. Причём я бы ещё понял, если бы проводились детальные исследования компиляторов, но о об их устройстве ни слова, всё сводится к замене труда компилятора на труд человека.


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

V>Есть такой анекдот: "Полиция следит за порядком, беспорядки их не интересуют". Если человек изначально пишет ошибки, чтобы другие догадались, то особого смысла в этом нет. С++ существует для решения задач, но какую задачу решал Вальяжный Учитель? Научиться чему-то можно лишь решая реальные задачи, а не имитируя несуществующие ошибки. Так что в глобальном плане я против такого метода обучения, а шестёрок вообще никто не спрашивал, на то они и шестёрки. С другой стороны прежде чем выбрать стараюсь рассматривать все возможности. Совсем не против почитать доводы в пользу таких тестов, аля забьём гвоздь тысячью и одним неправильным способом.


вы разницу между обучением и тестом представляете?
-n1l-
-n1l-
14.03.2015 11:40
Это конечно демагогия, но у меня есть довод в пользу таких тестов.
Если взять процесс, который сложнее забивания гвоздей, например создание красивой мебели, мягкой мебели, пусть в нем тоже будет забивание гвоздей.
Как научить человека делать красивую мебель? Никак. Вы не сможете показать ему все миллионы примеров, как надо в конкретном случае делать мебель.
Вы сможете научить его работать со станкам и инструментами, а вот делать мебель, он должен научится сам.
Путем практики, долгих треннировок и набитых шишех, от тех же гвоздей, ващ подопечный станет специалистом и знаете что, он будет пользоваться навыками, которые вы ему дали только в самых базовых случая, в основном он будет использовать уже свой, выработанный стиль работы, где гвозди в каркас для кожанного дивана забивают не под углом 90%, а под углом 100%-110%, что бы не согнуть гвоздь и не потрескать дорогую древесину.
smeeld
smeeld
14.03.2015 11:55
Здравствуйте, -n1l-, Вы писали:

N>Это конечно демагогия, но у меня есть довод в пользу таких тестов.


Принцип обучения всему что можно тут вспомнить выражается парадигмой "Делай как Я, когда научишься делать
как Я-делай как хочешь". Дыры в законах системы находят только те, кто эту систему знает в совершенстве.
Но это точно не работа изучающих систему. Это работа профессионалов, которая стоит денег.
-n1l-
-n1l-
14.03.2015 12:08
Вся правда в том, что это не так где-то в половине случаев.
velkin
velkin
14.03.2015 02:12
Здравствуйте, smeeld, Вы писали:

N>>Это конечно демагогия, но у меня есть довод в пользу таких тестов.

S>Принцип обучения всему что можно тут вспомнить выражается парадигмой "Делай как Я, когда научишься делать как Я-делай как хочешь". Дыры в законах системы находят только те, кто эту систему знает в совершенстве.
S>Но это точно не работа изучающих систему. Это работа профессионалов, которая стоит денег.

Довольно точно выражено. Неправильно ученики и сами смогут сделать. А доскональное исследование мелочей удел профи. Плюс всё же не все понимают, что компьютер нужен для замены человеческого труда, и притворяться им с бумажкой в руках очень глупо.
Tilir
Tilir
16.03.2015 09:55
Здравствуйте, velkin, Вы писали:

V>Ещё вопросы?


Условия обычные -- 40 минут и никуда не подглядывать


Возможно я забыл добавить что при выполнении этого теста использование компьютера недопустимо. Разумеется после того как группа его написала, я всем им дал бланк домой с пожеланием отнестись к этому как к лабораторной работе -- то есть откомпилировать, погонять, найти точные ответы на все вопросы. Разумеется я приветствую то, что вы тоже так сделали (кстати я бы на вашем месте компилировал с более ограничивающим набором опций -- там всякие Wall, Wextra, pedantic, все такое). Но вот выкладывать это сюда как-то некорректно. Вы лишаете друих радости этого открытия.
velkin
velkin
16.03.2015 12:41
Здравствуйте, Tilir, Вы писали:

T>Здравствуйте, velkin, Вы писали:

V>>Ещё вопросы?
T>

T>Условия обычные -- 40 минут и никуда не подглядывать

T>Возможно я забыл добавить что при выполнении этого теста использование компьютера недопустимо.

Я это прекрасно понял, отсюда и дальнейшие рассуждения о дурацких методах обучения программированию. Мы сторонники разных течений, как католическая и православная церковь, или как конструкторские бюро Королёва и Челомея, или как партии США республиканцев и демократов. Хотя в основе лежит программирование, но мои сторонники утверждают, что "кодирование компьютера без самого компьютера не бывает", а ваши напротив. Более того, мои сторонники выделили направление деятельности — системный анализ.

Конечно, здесь нет никакого спора, просто через много лет сторонники одних течений умрут, а новое поколение будет думать иначе. Есть такая книга "Кодеры за работой. Размышления о ремесле программиста", там как раз говорилось о том, что некоторые программисты думают, что компиляторы и отладчики создали некие комитеты по стандартизации.

Об авторе 8
Благодарности 9
Введение 11
Глава 1. Джейми Завински 15
Глава 2. Брэд Фицпатрик 55
Глава 3. Дуглас Крокфорд 93
Глава 4. Брендан Айк 129
Глава 5. Джошуа Блох 159
Глава 6. Джо Армстронг 191
Глава 7. Саймон Пейтон-Джонс 219
Глава 8. Питер Норвиг 255
Глава 9. Гай Стил 283
Глава 10. Дэн Ингаллс 321
Глава 11. Питер Дойч 357
Глава 12. Кен Томпсон 391
Глава 13. Фрэн Аллен 421
Глава 14. Берни Козелл 451
Глава 15. Дональд Кнут 491
Библиография 526
Алфавитный указатель 529

velkin
velkin
14.03.2015 12:37
Здравствуйте, Tilir, Вы писали:

T>И вот вчера группа неплохо написала мне простенький midterm тестик


Вспомнилось: "А теперь, дети, давайте повторим все те слова, которые нельзя произносить!"