Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Грабли, на которые мы наступаем


Автор: borisbn 6.2.2012, 20:44
Предлагаю собрать здесь ошибки, которые
  •  Проявляются только в рантайме (компайл-тайм неинтересен - такие ошибки находятся и исправляются просто)
  •  Встречаются довольно часто (необязательно у опытных программистов)
  •  Неочевидны как для для неопытных, так и для людей с опытом
Цель: избавить программистов (как опытных, так и не очень) от уймы потерянного времени.
Просьба: постить сюда ошибки, причину ошибки, и, самое главное, как уберечься от их совершения.

Итак.
1)
Код

// объект строка, который возвращается ф-цией functionThatReturnsStdString() "живёт" только в строке (1).
// как только выполнение переходит к строке (2), этого объекта уже нет. И, соответственно, указатель,
// который вернула c_str() будет указывать в никуда.
// При вызове ф-ции functionThatRequiresCharPtr() ей будет отдан невалидный указатель
const char * ptr = obj.functionThatReturnsStdString().c_str(); // (1)
functionThatRequiresCharPtr( ptr ); // (2)


2)
Код

std::list< int > objects;
for ( std::list< int >::iterator it = objects.begin(); it != objects.end(); ++it ) {
    std::list< int >::iterator found = objects.find( obj );
    if ( found != objects.end() ) {
        it = objects.erase( found );
    }
}
// в данном случае it меняется в цикле, а затем ему делается ++it. Нужно так
for ( std::list< int >::iterator it = objects.begin(); it != objects.end(); /* здесь ++it не нужно */ ) {
    std::list< int >::iterator found = objects.find( objToRemove );
    if ( found != objects.end() ) {
        it = objects.erase( found );
    }
    else
        ++it;
}
// а лучше так
std::list< int >::iterator theLast = std::remove ( objects.begin(), objects.end(), objToRemove );


3)
Код

// Не знаю, как у вас, но у меня такая ошибка периодически всплывает:
// я, почему-то, уверен, что resize "пробивает" нулями ВСЕ значения вектора, а не только те, которые добавляются ф-цией resize
void Object::resizeAndReset( int count ) {
    m_vector.resize( count, 0 );
}

Автор: boostcoder 6.2.2012, 21:14
на первый пример недавно наткнулся. потратил часа 4 на поиски бага. весь моцг себе вынес ### smile 
но самое смешное это то, что код я написал за час!

Автор: fish9370 6.2.2012, 21:35
функция возвращает список регулярных файлов в директории..

Код

int browse_dir(char **matches, int m_size, char *buff, int b_size, int *start, char *dir, const char *prefix) {
        int n = 0;
        DIR *dirp = opendir(dir);
        struct dirent *dp;
        struct stat file_info;

        char path[PATH_MAX];

        int p_len = strlen(prefix);
        while ((dp = readdir(dirp)) != NULL) {
                snprintf(path, sizeof(path), "%s/%s", dir, dp->d_name);
                lstat(path, &file_info);
                if (S_ISREG(file_info.st_mode) && (!p_len || strncmp(dp->d_name, prefix, p_len) == 0)) {
                        int end = strlen(dp->d_name);
                        matches[n++] = strncpy(buff + (*start), dp->d_name, b_size - (*start));
                        (*start) += end;
                        buff[(*start)++] = ';';
                }
        }

        closedir(dirp);
        return n;
}



это набросок одной из функций, которая мне нужна, в нем две грубейшие ошибки..
пожалуйста назовите их..


Автор: feodorv 6.2.2012, 23:24
Цитата(fish9370 @  6.2.2012,  21:35 Найти цитируемый пост)
пожалуйста назовите их..

Честно говоря, тема не об этом... Ошибок много:
Цитата(fish9370 @  6.2.2012,  21:35 Найти цитируемый пост)
buff[(*start)++] = ';';

Не проверяется выход за пределы буфера.

Цитата(fish9370 @  6.2.2012,  21:35 Найти цитируемый пост)
(*start) += end;

при выходе за пределы буфера start будет показывать мимо буфера

Цитата(fish9370 @  6.2.2012,  21:35 Найти цитируемый пост)
matches[n++] = 

Тут тоже нужно вставить проверку, что вы не превысили лимит m_size...

Цитата(fish9370 @  6.2.2012,  21:35 Найти цитируемый пост)
lstat(path, &file_info);

Не проверяется возвращаемое значение, а вдруг файла уже нет... или PATH_MAX не хватило... и в file_info мусор...

Цитата(fish9370 @  6.2.2012,  21:35 Найти цитируемый пост)
int p_len = strlen(prefix);

Раз plen может оказаться нулевой, то было бы неплохо перед strlen проверить prefix на NULL, если, конечно, Вы не пользуетесь исключительно browse_dir( ..., "");

Цитата(fish9370 @  6.2.2012,  21:35 Найти цитируемый пост)
int n = 0;

Если предполагается, что в matches ещё ничего нет, то нужно правильно проинициализировать start: *start = 0;

Цитата(fish9370 @  6.2.2012,  21:35 Найти цитируемый пост)
DIR *dirp = opendir(dir);

dirp не проверяется на NULL...

Ну и можно в конце сделать buff[*start] = '\0', если место ещё оставалось... И конечную ';' (если она есть) поглотить, но я не знаю, как буфер будет использоваться дальше...

Автор: borisbn 7.2.2012, 08:28
Цитата(boostcoder @  6.2.2012,  21:14 Найти цитируемый пост)
 потратил часа 4 на поиски бага

Цитата(boostcoder @  6.2.2012,  21:14 Найти цитируемый пост)
код я написал за час

ну дык, стандарт: 20/80. ну, почти smile

Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)
Честно говоря, тема не об этом...

 smile Честно говоря, вообще не понял, зачем этот код ? Тема то не для того, чтобы искать чужие ошибки, а чтобы показывать часто встречаемые ошибки, на поиск которых уходит куча времени.
По поводу выхода за границы массива - пользуйтесь STL.

Автор: fish9370 7.2.2012, 09:56
feodorv, спасибо за работу

Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)
dirp не проверяется на NULL...


да..

Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)
Не проверяется возвращаемое значение, а вдруг файла уже нет... или PATH_MAX не хватило... и в file_info мусор...


соглашусь, добавим эту проверку

Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)

Раз plen может оказаться нулевой, то было бы неплохо перед strlen проверить prefix на NULL, если, конечно, Вы не пользуетесь исключительно browse_dir( ..., "");


нет, исключительно не пользуюсь, но вызывающая сторона гарантирует, что префикс не равен NULL, хотя, я Вас услышал..

Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)
Тут тоже нужно вставить проверку, что вы не превысили лимит m_size...


возможно индексное переполнение - это была первая грубая ошибка..


Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)
Не проверяется выход за пределы буфера.


Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)
при выходе за пределы буфера start будет показывать мимо буфера


возможно переполнение - это вторая грубая ошибка 


Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)
Если предполагается, что в matches ещё ничего нет, то нужно правильно проинициализировать start: *start = 0;


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


Цитата(feodorv @  6.2.2012,  23:24 Найти цитируемый пост)
И конечную ';' (если она есть) поглотить, но я не знаю, как буфер будет использоваться дальше...


это не требуется..

Добавлено @ 10:04
Цитата(borisbn @  7.2.2012,  08:28 Найти цитируемый пост)
По поводу выхода за границы массива - пользуйтесь STL.


извините, забыл напомнить, я пишу исключительно на Си (не считая скриптовых языков)


Цитата(borisbn @  7.2.2012,  08:28 Найти цитируемый пост)
Честно говоря, вообще не понял, зачем этот код


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

Автор: boostcoder 7.2.2012, 10:48
borisbn, попроси модераторов чтоб удалили все начиная с третьего поста.

fish9370, буду знать, какой код ты пишешь ;)

Добавлено через 30 секунд
или со второго) он тоже оффтоп.

Автор: newbee 7.2.2012, 11:00
Сложно вспомнить какие-то конкретные часто повторяющиеся проблемы. Но если в целом охарактеризовать грабли, на которые я периодически наступаю, - это необходимость писать на С++. Ниже я приведу немного конкретики, но без примеров кода. Если захотите кода по определенным пунктам, его есть у меня.

Вот тут на форуме один чувак... volatile или как-то так... просто прется, что С++ остается все таким же "простым" и делает именно то, что требует от него программист. С моей точки зрения, для языка, позиционирующего себя как высокоуровневый, с настолько переусложненным синтаксисом, продолжать оставаться надстройкой над ассемблером недопустимо. В стандартной библиотеке языка все пучком... Конечно в ней очень многого не хватает, но в целом хотя бы ее дизайн очень хорош. Но в core language писать и не удивляться на неочевидности невозможно!
  • Идиотская политика неявного приведения типов, когда по ошибке в foo(bool) передаешь "хеллоу", а компилятор ест и не краснеет. Это допустимо в операторах и функциях сравнения, но не где попало!
  • Совершенно дурацкий механизм опредления пользовательских операторов преобразования типов.
  • Кривая идеология конструирования объектов, когда конструктов вызывается где-то посреди процесса собирания нового объекта.
  • Норкоманское множественное наследование с эпичным костылем в виде виртуального наследования.
  • Кастрированные лямбда-функции.
  • Сказочные танцы с указателями на члены классов, особую пикантность придает уже упомянутое выше виртуальное наследование.
  • Чрезвычайно переусложненный механизм метапрограммирования, и сразу на двух языках: сишный #define и темплейты. Хотя конечно плюсисты слишком задрали нос, называя темплейты метапрограммирванием.
На эти грабли я наступила примерно за неделю писания на С++! Не уверена, что это все прелести языка, но пока в голову больше ничего не приходит...

Автор: borisbn 7.2.2012, 11:09
Цитата(boostcoder @  7.2.2012,  10:48 Найти цитируемый пост)
 попроси модераторов чтоб удалили все начиная с третьего поста.

done. кроме сообщ. newbee

Автор: newbee 7.2.2012, 12:18
Цитата(boostcoder @  7.2.2012,  13:09 Найти цитируемый пост)
минусовщина стразу трем пользователям
Это я начала) Слушала одноименную с минусом песню ленинграда, читала тему и как-то не удержалась (

Цитата(boostcoder @  7.2.2012,  13:09 Найти цитируемый пост)
на лицо психическая неуравновешенность ;) 
Напротив, поциент демонстрирует способность к социальной адаптации. Код читается так: если в теме встречается юзернейм "бусткодер", я затыкаюсь и ухожу.

smile

Автор: Static 7.2.2012, 12:29
эээ, народ... спокойно!

мое любимое:
Код

if ( getSomething() );
    doSomething();

// или

while ( doSomething() );
    doSomethingElse(); // но это слишком легко обнаружить


Еще, когда только начинал работать, - отлично прошелся по конструкторам копирования. Точнее, по их отсутствию)

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

Еще вот такое
Код

void initSomethingImportant()
{
    assert( init_very_important_lib() && "init library fail" );
    
    important_lib::start( "some_params" );
}

В релизе, естественно, падает =)

Сейчас еще, может, чего-нибудь вспомню.

Автор: boostcoder 7.2.2012, 12:38
Цитата(newbee @  7.2.2012,  12:18 Найти цитируемый пост)
поциент

полагаю, намек на происхождение от слова http://lurkmore.to/%D0%9F%D0%BE%D1%86 ;)

Добавлено через 4 минуты и 1 секунду
newbee, про виртуальную хрень и наследование ты же в курсе: используй функциональный стиль. С++ при этом становится как Си_на_стеройдах!

Автор: borisbn 7.2.2012, 12:47
Цитата(newbee @  7.2.2012,  11:00 Найти цитируемый пост)
Кривая идеология конструирования объектов, когда конструктов вызывается где-то посреди процесса собирания нового объекта.

про остальное, вроде, понял, а это - никак не пойму. чойта ?

Автор: newbee 7.2.2012, 12:54
Цитата(borisbn @  7.2.2012,  13:47 Найти цитируемый пост)
про остальное, вроде, понял, а это - никак не пойму. чойта ? 
Вызови из конструктора виртуальный метод например.

Цитата(boostcoder @  7.2.2012,  13:38 Найти цитируемый пост)
используй функциональный стиль
ФП не панацея, в С++ ФП неудобен. /*Смотрела недавно бустовский феникс, не знала плакать или смеяться*/

Автор: borisbn 7.2.2012, 13:03
Цитата(newbee @  7.2.2012,  12:54 Найти цитируемый пост)
Вызови из конструктора виртуальный метод например.

не вижу проблем... да, поведение будет отличаться от вызова той же функции не из конструктора.
на момент работы конструктора базового класса виртуальной таблицы наследника не существует, как и самого наследника.
это как если бы папа и сын родились одновременно smile

Автор: newbee 7.2.2012, 13:18
Цитата(borisbn @  7.2.2012,  14:03 Найти цитируемый пост)
поведение будет отличаться от вызова той же функции не из конструктора.
Это нормально, когда одно и то же действие над одним и тем же объектом без воздействия видимых внешних факторов имеет несколько разных поведений? Это нормально, когда для нормальной инициализации (в широком смысле) объекта приходится вручную городить методы инициализации и не забывать вызывать их в конструкторах наследников?

Цитата(borisbn @  7.2.2012,  14:03 Найти цитируемый пост)
на момент работы конструктора базового класса виртуальной таблицы наследника не существует, как и самого наследника.
Вот я и написала: конструктор вызывается где-то посреди процесса создания объекта.

Автор: mes 7.2.2012, 15:42
newbee, с каким из императивных языков ведешь сравнение С++ ? 
сразу отмечу, что сравнение с Шарпом не честное, так как конечный код выполняется в разных средах... также как и с любимым некоторыми Обероном... 
если с Делфи, то лично я сбежал с него на С++ в силу ограниченности первого.. 
если просто как критика С++, то соглашусь со многим, но тут надо учесть, что С++ язык естесственного развития, плюс нацеленный на высокую производительность, что, к сожалению, выливается в кривизне многих решений.. И все  упирается в вопрос , а где ж (императивная) альтернатива ?!

Автор: borisbn 7.2.2012, 15:45
mes, не думаю, что у Вас есть грабли, но может поищете в загажниках ? Ну признайтесь, приходилось же наступать хоть дважды ? Может не в своём коде, а в том, который приходилось инспектировать ? 

Автор: Artemon 7.2.2012, 15:51
Код

for(int k = 0; k < 100; k++)
   {
    for(int j = 0; j < 100; k++)
        {
        }
   }


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

Автор: newbee 7.2.2012, 17:01
Цитата(mes @  7.2.2012,  16:42 Найти цитируемый пост)
newbee, с каким из императивных языков ведешь сравнение С++ ? 
Ни с каким конкретным языком я не сравнивала, а старалась выделить объективные недостатки. Естественно мое мнение по определению субъективно, но оглядываясь на отзывы других трезвых плюсистов и тем, что даже тут вроде как все согласны с моими тезисами, склоняюсь считать это мнение более или менее объективным.

Цитата(mes @  7.2.2012,  16:42 Найти цитируемый пост)
если с Делфи, то лично я сбежал с него на С++ в силу ограниченности первого..
Громкое заявление. Делфи немодный и умирающий, но ограниченный... Обычно программисты в С++ стараются сделать некоторые вещи "как в Делфи", но не наоборот.

Цитата(mes @  7.2.2012,  16:42 Найти цитируемый пост)
надо учесть, что С++ язык естесственного развития, плюс нацеленный на высокую производительность
С каких пор развитие отменяет необходимость переработки? Нынешняя политика развития, основанная не внесение нового, привела к тому, что образовался снежный ком из кучи разнообразных лексем, конструкций, их комбинаций и тяжело вдупляемоей семантики.

Цитата(mes @  7.2.2012,  16:42 Найти цитируемый пост)
И все  упирается в вопрос , а где ж (императивная) альтернатива ?!
В этот вопрос вообще ничего не упирается на самом деле. Кривизна С++ не зависит от наличия альтернатив. Тот же C#, с которым ты почему-то запретил сравнивать, намного лучше и логичней... Мы ведь рассматриваем языки, а не платформы. А для меня альтернативой стал CL ;).

Автор: mes 7.2.2012, 19:17
Цитата(newbee @  7.2.2012,  16:01 Найти цитируемый пост)
 Тот же C#, с которым ты почему-то запретил сравнивать, намного лучше и логичней...

потому что С# является языком развитой ОО-среды, и был заточен под нее.. С++ ж ложится на плоскую Ось, добавляя для нее ООП примитивы, но при этом не сильно отходя, чтоб оставаться системным языком.. 

Цитата(newbee @  7.2.2012,  16:01 Найти цитируемый пост)
Мы ведь рассматриваем языки, а не платформы

Увы,  некотрые недостатки С++ тянут корни именно от платформы.. в следствии его "системопредназначености" и не учитывать этого нельзя... 

Цитата(newbee @  7.2.2012,  16:01 Найти цитируемый пост)
Обычно программисты в С++ стараются сделать некоторые вещи "как в Делфи", но не наоборот.

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

Цитата(newbee @  7.2.2012,  16:01 Найти цитируемый пост)
 Нынешняя политика развития, основанная не внесение нового

не на невнесение нового, а
1. внесение только того, что требуется (буст кстати служит полигоном для отработки новых идей)
2. незатрагиванием старого (обратная совместимость... бррр, но объем старого кода того требует)

Цитата(newbee @  7.2.2012,  16:01 Найти цитируемый пост)
что образовался снежный ком из кучи разнообразных лексем, конструкций, их комбинаций и тяжело вдупляемоей семантики.

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

Добавлено через 1 минуту и 7 секунд
другой вопрос, что затянули они с этим стандартом.. его бы года 3 назад, как раз в пору пришлось бы... 


Автор: mes 7.2.2012, 19:45
Цитата(borisbn @  7.2.2012,  14:45 Найти цитируемый пост)
не думаю, что у Вас есть грабли, но может поищете в загажниках ? Ну признайтесь, приходилось же наступать хоть дважды ? 

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

Случай первый: Программа вроде бы идеально работала, поко я не установил себе google desktop.. После этого начились вылеты.. после деинсталяции оного приложения, прога заработала снова на ура..  оказалось я забыл обнулить один указатель член класса..

Случай два произошел из за того, что (упростим картину) в деструкторе одного статического объекта,   было обращение к другому статическому.. 
В зависимости от "порядка компиляции"  появлалась ошибка сегментации при закрытии проги.. 
http://forum.vingrad.ru/forum/topic-216957/anchor-entry1552332/0.html

Больше "серьезных" (для полугодовалого знакомства с языком не было) ошибок, которые бы заставляли попотеть не было..
Хотя для обнаружения этих от дебагера понадобился лишь стек вызовов - смущало скорее всего лишь неправдоподобие ситуации.. 
 smile 

Автор: newbee 7.2.2012, 21:20
Ну... Все эти аргументы об "особенности" с++... и ось плоская, и системный... не выдерживают никакой критики. Страуструпу никто не мешал сделать нормальное ОО-расширение си,.. примеров хороших реализаций ООП уже было... но он сделал то, что сделал. Да и дело то вовсе не в ООП ведь, а в целом в хаотической сущности языка, нет стройности. И еще порцию идиотизма приносят обсаженные авторы всеми здесь любимого буста, половина библиотек которого формально следуют синтаксису с++, но де-факто расширяют его, причем самым дебильным способом - переопределением операторов. Две стоящие друг за другом строки a % b % c могут делать совершенно разные вещи, выдавать абсолютно невдупляемые ошибки компиляции, но зато блядь круто-то как!

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

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

Цитата(mes @  7.2.2012,  20:17 Найти цитируемый пост)
увы, но с выходом нового стандарта появление новых инструментов перекрыло множество логических прошлых дыр, и для того чтоб программить, не нужно знать устаревший ком, оставленный для совместимости
Ты можешь назвать хоть одну родовую травму С++, которую перекрыл новый стандарт?

Добавлено через 8 минут и 12 секунд
Не хочу скатывать тему в холивор с собой в главные роли, поэтому в дальнейшем воздержусь тут от пустого балабольства. Просили высказаться по поводу граблей - я высказалась)) Ну если у кого будет здоровая аргументация, обязательно вернусь )

Автор: mes 8.2.2012, 00:04
Цитата(newbee @  7.2.2012,  20:20 Найти цитируемый пост)
 Страуструпу никто не мешал сделать нормальное ОО-расширение си

так есть же объективС, что ж все на него не перейдут, раз Страуструп ерунду придумал ?
 
Цитата(newbee @  7.2.2012,  20:20 Найти цитируемый пост)
примеров хороших реализаций ООП уже было... но он сделал то, что сделал

эх не люблю я чистое  ООП... 

Цитата(newbee @  7.2.2012,  20:20 Найти цитируемый пост)
Но то, что сделано криво, могло быть сделано прямо.

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

Цитата(newbee @  7.2.2012,  20:20 Найти цитируемый пост)
Ты можешь назвать хоть одну родовую травму С++, которую перекрыл новый стандарт?

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

Добавлено через 2 минуты и 48 секунд
Цитата(newbee @  7.2.2012,  20:20 Найти цитируемый пост)
. И еще порцию идиотизма приносят обсаженные авторы всеми здесь любимого буста, половина библиотек которого формально следуют синтаксису с++, но де-факто расширяют его, 

в этом и есть одна и затей буста.. опробывать в какую сторону менять язык )

Цитата(newbee @  7.2.2012,  20:20 Найти цитируемый пост)
Две стоящие друг за другом строки a % b % c могут делать совершенно разные вещи,

а я наоборот люблю это, правда когда с умом продуманы операторы smile



Автор: volatile 8.2.2012, 00:08
Цитата(newbee @  7.2.2012,  11:00 Найти цитируемый пост)
Вот тут на форуме один чувак... volatile или как-то так... просто прется, что С++ остается все таким же "простым" и делает именно то, что требует от него программист. 

Я понимаю конечно,  что лисп (или как-то так...), делает совершенно не то что требует от негго программист.
Но это вовсе не основание, чтобы такую затею переносить на С++
Пишите на лиспе. Что вам от С++ то нужно?


Автор: newbee 8.2.2012, 00:30
volatile, я рада, что смогла вытащить твою грудь на амбразуру в защиту любимого языка, но может быть все же скажешь что-нибудь не только в пустоту? Я за лиспы тут не агитирую и вообще, хоть и разбавляю свои комментарии изрядной порцией экспрессии и баловства, но все же пишу о вполне конкретных вещах.

Автор: boostcoder 8.2.2012, 00:40
Цитата(mes @  8.2.2012,  00:04 Найти цитируемый пост)
почему до сих пор этот препроцессор не развили

такой, какой он сейчас - его вовсе запретить нужно!
тот же bash - как скриптовый микро-ЯП, в разы лучше(массивы/словари/карты/функции). и синтаксис не самый сложный(как у перл). почему бы что-то подобное не делает препроцессор?


ну а newbee могу лишь сказать то, что говорю обычно: чем виноват тебе инструмент, если ты им пользоваться не умеешь?

Автор: borisbn 8.2.2012, 08:52
История mes о google desktop напомнила...

Как-то 29 марта (это существенно) подходит ко мне молодой коллега Дима и говорит, что наша программа не пишет в БД. Я, ессно, спрашиваю "что менял" - отвечает "ничего". Ставим старую версию программы - не пишет. Ставим старую версию базы - не пишет. И так продолжалось 3 дня. 1-го апреля подходит Дима и говорит, что программа стала писать в БД. Я думал первоапрельский розыгрыш. Пошёл проверил. Старая версия программы в старую версию БД пишет. Новая - тоже...
В итоге что выяснилось: эту программу писали давным-давно ещё под DOS. Дима же переделывал её под Windows. В DOS в структуре, в которой хранится дата, месяц считается от 0, а в windows'овской структуре - от единицы. При записи в базу старый формат даты преобразовывался в новый без учёта этой особенности. Таким образом получалось, что мы пытались записать в БД 29 февраля, затем 30-е, затем 31-е... СУБД отказывалась воспринимать эти даты, а вот первое марта - пожалуйста.
Как никто не заметил, что дата в БД отличается на месяц - не знаю smile

Автор: Earnest 8.2.2012, 10:04
fish9370, веди себя прилично!
borisbn, ты тоже. Когда один хамит, а другой отвечает тем же - виноваты оба!
Последние два сообщения, пожалуй, удалю, чтобы не портить впечатления от темы.
...
Так, уже не два, бусткодер и ньюби подключились к срачу. Вам что, господа, делать нечего совсем?
Рабочий день на дворе! smile  smile  smile 

Автор: borisbn 8.2.2012, 10:16
Earnest, сорри, что сорвался, но достал он уже хамить. Кста, и я тоже
Цитата(boostcoder @  8.2.2012,  10:07 Найти цитируемый пост)
ожидал модерации...

smile

Цитата(Earnest @  8.2.2012,  10:04 Найти цитируемый пост)
Рабочий день на дворе!

всё, всё, всё... действительно, работать надо.
/me пошёл делать очередные грабли ))

Автор: newbee 8.2.2012, 10:31
Не флейма ради, на справедливости для, я продублирую свое удаленное сообщение: фишка, выкладывай уже ссылки на свои программы. Желательно в отдельную тему, там и будем смотреть, пока пустой треп от тебя. А потом, как создашь тему, попросим модераторов в очередной раз подчистить тут.

Автор: Earnest 8.2.2012, 11:15
Это пожалуйста. Хотите померять чей-то код - не проблема. Но в отдельной теме. И интеллигентно. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)