Сравнение компиляторов Visual С++ 6 и Microsoft Visual Studio 2008
1. Действительно ли настолько лучше или разница не большая, хотелось бы ссылку на статью с тестами этих версий межу собой или как то самому можно это выяснить?
Если нет практически ни какой разницы тогда ещё два вопросика:
2. В Microsoft Visual С++ 6 размер SP6 примерно в два раза меньше чем SP5, это значит что я должен для нормальной работы установить SP5, а затем SP6, я то думал что все заплатки из старого SP переходят в новый и плюс новые заплатки?
3. зачем нужно в Microsoft Visual С++ 6 при использовании функции timeGetTime​ подключать библиотеку
#pragma comment(lib, "winmm.lib"), а если не подключать библиотеку, то при запуске программы возникает ошибка
text.obj : error LNK2001: unresolved external symbol __imp__​timeGetTime@0, я её в компиляторе borland не подключал она и так работала, да и во многих примерах для Microsoft Visual не написано про это?
Помогите пожалуйста разобраться.
Говорят в Microsoft Visual Studio 2008 Professional Edition компилятор существенно лучше. Скомпилированные программы работают быстрее, чем в Microsoft Visual С++ 6.
1. Действительно ли настолько лучше или разница не большая, хотелось бы ссылку на статью с тестами этих версий межу собой или как то самому можно это выяснить?
Лучше - это не обязательно быстрее.
Версия компилятора 2008 ЗНАЧИТЕЛЬНО лучше поддерживает стандарт C++, генерирует более безбажный код. Что касается скорости работы результирующего кода, то тут тоже выигрыш за счет лучшей оптимизации и встренного профилировщика.
Но дело не только в компиляторе, но и в самой среде разработке. Версия 2008 значительно удобнее и обладает множеством дополнительных полезных инструментов.
Зачем пользоваться старинной версией, если есть нормальная (не какая-нибудь глючная бета) новая версия?
3. зачем нужно в Microsoft Visual С++ 6 при использовании функции timeGetTime​ подключать библиотеку
#pragma comment(lib, "winmm.lib"), а если не подключать библиотеку, то при запуске программы возникает ошибка
text.obj : error LNK2001: unresolved external symbol __imp__​timeGetTime@0, я её в
За тем, что ф-ция timeGetTime​ определена в библиотеке Winmm.lib, которую нужно подкючить.
компиляторе borland не подключал она и так работала
значит, она подключалась там автоматически, что не очень хорошо
да и во многих примерах для Microsoft Visual не написано про это?
а зачем писать очевидные вещи?
открой описание ​timeGetTime в MSDN, там все написано
я не писал сложных проектов, но в студенческой практике наткнулся на косяк VC++6:
код содержащий рекурсию, при оптимизации по скорости, компилировался не верно. Программа работала, но результаты были полностью некорректны.
при этом оптимизация по минимализации кода на выходе давала рабочую программу.
поставил 2008 студию, собрал проект с оптимизацией по скорости, и о чудо - я получил правильно работающую программу!
я не писал сложных проектов, но в студенческой практике наткнулся на косяк VC++6:
код содержащий рекурсию, при оптимизации по скорости, компилировался не верно. Программа работала, но результаты были полностью некорректны.
при этом оптимизация по минимализации кода на выходе давала рабочую программу.
поставил 2008 студию, собрал проект с оптимизацией по скорости, и о чудо - я получил правильно работающую программу!
Пример в студию!
Есть подозрение, что в данном случае проблема не в компиляторе, а в твоем коде. Возможно, различного рода наведенные ошибки, к примеру, buffer overflow.
PS: Поддерживаю тов. Green'а - незачем использовать старый компилятор кроторый плохо соответствует стандарту да и не только стандарту ибо его разработчики без дела не сидят уж поверьте.
Есть подозрение, что в данном случае проблема не в компиляторе, а в твоем коде. Возможно, различного рода наведенные ошибки, к примеру, buffer overflow.
Сам долго мучался пытаясь понять в чем косяк. Нашелся добрый человек с бОльшим опытом, объяснивший что вот это(обход бинарного дерева):
{
char n[256] = "";
strcpy(n, c);
if ((*node).top != NULL)
{
createCodes((*node).top, strcat(n, "1"), codes);
} else {
strcat(codes[(*node).topVal], strcat(n, "1"));
}
strcpy(n, c);
if ((*node).bottom != NULL)
{
createCodes((*node).bottom, strcat(n, "0"), codes);
} else {
strcat(codes[(*node).bottomVal], strcat(n, "0"));
}
}
оптимизируется 6 студией неверно(причем именно по скорости если оптимизировать).
Сам проверить утверждение пока не берусь, с плюсами еще на "Вы" (до этого 2 года писал на Delphi без углубления в отладку и ассемблер).
Сейчас просто вынужден разбираться в С/C++ и асме(программа ВУЗа).
Аргументы? Буду рад, т.к. знаю, что учиться надо =)
Только сразу скажу: меня бесят утверждения, что нужно писать:
вместо
(и им подобные)
оба варианта синтаксически верны(и, как говорится, "попробуйте доказать обратное")
Код, действительно, ТИХИЙ УЖАС!
Я рекомендую: прежде чем что-то писать на C/C++, прочитать хотябы одну книжку (любую) по этому языку!
Для начала я "причешу" твой код, чтоб он был похож на код C:
{
char n1[256] = "";
strcpy(n1, c); // нет проверки на длину строки, откуда уверенность, что не будет buffer overflow?
strcat(n1, "1"); // а где проверка, что не будет buffer overflow?
// откуда уверенность, что указатель node валиден?
if (node->top != NULL) // автор явно не читал ничего по C++, раз не знает про оператор ->
{
createCodes(node->top, n1, codes);
}
else
{
strcat(codes[node->topVal], n1); // где проверка, что node->topVal не указывает за границы массива codes?
//а где проверка, что не будет buffer overflow при strcat?
}
// далее аналогично, с аналогичными замечаниями
char n2[256] = "";
strcpy(n2, c);
strcat(n2, "0");
if(node->bottom != NULL)
{
createCodes(node->bottom, n2, codes);
}
else
{
strcat(codes[node->bottomVal], n2);
}
}
Из комментариев к коду становится ясно, что автору рановато критиковать компилятор, т.к. его код сам по себе один сплошной баг!
Для меня остается загадкой, что делает эта функция. Какая-то она нелепая... Да и не понять, зачем для "обхода бинарного дерева" нужны строковые переменные?
Но приведу код к виду C++:
{
string n1 = c + "1";
if (node.top != NULL)
{
createCodes(node.top, n1, codes);
}
else
{
codes[node.topVal] += n1;
}
string n2 = c + "0";
if (node.bottom != NULL)
{
createCodes(node.bottom, n2, codes);
}
else
{
codes[node.bottomVal] += n2;
}
}
Только сразу скажу: меня бесят утверждения, что нужно писать:
вместо
(и им подобные)
оба варианта синтаксически верны(и, как говорится, "попробуйте доказать обратное")
В зависимости от того, что такое A, верным может быть как только первая запись, так и только вторая, обе или ни одна.
Код, действительно, ТИХИЙ УЖАС!
Я рекомендую: прежде чем что-то писать на C/C++, прочитать хотябы одну книжку (любую) по этому языку!
Постепенно читается.
Для начала я "причешу" твой код, чтоб он был похож на код C:
коменты там же:
{
char n1[256] = "";
strcpy(n1, c); // проверки нет, т.к. условие задачи ВСЕГДА ограничено 256 элементами
strcat(n1, "1"); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// откуда уверенность, что указатель node валиден?
if (node->top != NULL) // автор явно не читал ничего по C++, раз не знает про оператор ->
//автору пока проще разыменовывать указатели чтоб не путаться где что
{
createCodes(node->top, n1, codes);
}
else
{
strcat(codes[node->topVal], n1); // где проверка, что node->topVal не указывает за границы массива codes?
все в условии задачи. ни одно значение не может быть больше 255
//а где проверка, что не будет buffer overflow при strcat?
}
// далее аналогично, с аналогичными замечаниями
char n2[256] = "";
strcpy(n2, c);
strcat(n2, "0");
if(node->bottom != NULL)
{
createCodes(node->bottom, n2, codes);
}
else
{
strcat(codes[node->bottomVal], n2);
}
}
Из комментариев к коду становится ясно, что автору рановато критиковать компилятор, т.к. его код сам по себе один сплошной баг!
Не сплошной, но один нашел, кстати говоря не известно еще чей он ;)
а теперь о баге:
createCodes((*node).top, strcat(n1, "1"), codes);
или так:
createCodes(node->top, strcat(n1, "1"), codes);
кому как нравится, суть не в этом
из MSDN:
strcat
Append a string.
char *strcat( char *strDestination, const char *strSource );
Return Value
Each of these functions returns the destination string (strDestination). No return value is reserved to indicate an error.
теперь объясните мне пожалуйста, почему если функция возвращает указатель на результат объединения, то вариант указаный выше не работает? зато работает указаный ниже:
strcat(n1, "1");
createCodes((*node).top, n1, codes);
или так:
createCodes(node->top, n1, codes);
мы в обоих случаях передаем указатель на результат, тогда какого простите ХУдожника, первый вариант VC6 оптимизирует некорректно?
Для меня остается загадкой, что делает эта функция. Какая-то она нелепая... Да и не понять, зачем для "обхода бинарного дерева" нужны строковые переменные?
для того, чтоб в конце прохода иметь в строке "путь" от корня к веткам
все в условии задачи. ни одно значение не может быть больше 255
А в условии задачи сказано про ноль? Про терминальный символ цешной строки вы не забыли?
для того, чтоб в конце прохода иметь в строке "путь" от корня к веткам
Маргинальненько.
кому как нравится, суть не в этом
Как раз таки суть в мелочах, ибо в конце концов такой мусоро-помойный код приводит как минимум к большому мешку травы под столом, как максимум к посылу его аффтора на очередную итерацию, а при стремлении количества таких итераций к бесконечности к посылу на вольные хлеба.
Ну раз уж пример в студии, можете привести набор входных данных, с которомы код работал неверно при оптимизации по скорости?
Вопрос: Сколько программистов надо для того чтобы закрутить лампочку?
Ответ: 10 (один крутит, а остальные говорят что сделали бы это лучше)
Это к тому, что для некоторых задач лучше использовать рекурсию код становится проще и понятней. То что в коде нет проверок конечно нехорошо, но сейчас обсуждается вопрос о неправильной компилляции.
2 _DelphiN_ Хотелось бы посмотреть полный код программы, а не один кусок.
То что в баке нет бензина, - это, конечно, нехорошо, но сейчас обсуждается вопрос о том, что машина не заводится. :)
В данном коде все на столько примитивно, что я уверен, что проблема не в компиляторе, а в самом коде.
Какой смысл "обсуждать вопрос о неправильной компиляции", если неправильна не компиляция, а сам код?
Считаете иначе, докажите, что код был скомпилирован неправильно.
Если код выполняет не то, что хотелось - это ещё не значит, что виноват компилятор. А в 99% случаев виноват именно НЕ компилятор.
теперь объясните мне пожалуйста, почему если функция возвращает указатель на результат объединения, то вариант указаный выше не работает? зато работает указаный ниже:
strcat(n1, "1");
createCodes((*node).top, n1, codes);
или так:
createCodes(node->top, n1, codes);
мы в обоих случаях передаем указатель на результат, тогда какого простите ХУдожника, первый вариант VC6 оптимизирует некорректно?
Что значит "не работает" ?
Что значит "оптимизирует некорректно" ?
А работают по-разному хотя бы потому, что в первом варианте есть strcat(n1, "1"), а во втором этой операции нет. :)
Что значит "оптимизирует некорректно" ?
"не работает" - значит программа выдает неверный результат.
"оптимизирует некорректно" - значит, что тот же самый код, скомпилированный с теми же параметрами оптимизации, но в 2008 студии - работает корректно, т.е. выдает правильный результат.
А работают по-разному хотя бы потому, что в первом варианте есть strcat(n1, "1"), а во втором этой операции нет. :)
во втором случае поторопился и чутка не то скопипастил.
суть в том, что если мы заранее объединяем строки:
createCodes((*node).top, n1, codes);
то программа отрабатывает правильно.
если сделать так:
то результаты будут совершенно не те, которые нужны.
хотя в обоих случаях передается указатель на результат объединения(и в обоих случаях 2008 студия компилит код так, что он выдает верные данные)
Ну раз уж пример в студии, можете привести набор входных данных, с которомы код работал неверно при оптимизации по скорости?
хм... с каких пор входные данные влияют на оптимизацию(особенно данные не заложенные в программу)?
входные данные динамически генерируются в результате предшествующих функций. в частности строится дерево на основе структуры:
{
Node* top;
Node* bottom;
int topVal;
int bottomVal;
}
а дерево в свою очередь зависит от входного файла, который может содержать любую информацию.
так что не совсем понимаю вопроса о входных данных.
Понимаешь, что он на столько ужасный, что не известно, как он будет работать при разных входных значениях?
Поэтому, приведи тестовый пример (код программы полностью, а не одну функцию, и набор данных) на которой у тебя "не работает".
P.S. Код тестовой программы полностью - значит вырезанный код именно того куска, который не работает, обернутый так, чтоб он мог существовать, как законченная программа. Т.е. не всю твою поделку с миллионом функций, а минипрограмма под одну функцию.
Набор входных данных не забудь и правильный результат для сравнения.
Да с самых древних времен.
Если у тебя stackoverflow (а я уверен, что он у тебя и случается), то наведенные ошибки могут быть какие угодно!
Ты понимаешь, что такое stackoverflow? Почему он у тебя весьма вероятен, понимаешь?
К чему он приводит, понимаешь?
в одном из моих постоя я пытался добиться от вас ответа, почему 2 практически одинаковых куска кода, работают по-разному, при оптимизации по скорости в VS C++ 6, но вы решили придраться к мелочи.
вот перефразированный вопрос: http://forum.codenet.ru/showpost.php?p=298838&postcount=17
надеюсь теперь вы ответите на конкретно поставленый вопрос "почему так происходит?". В противном случае считаю ваши обвинения необоснованными.
вот перефразированный вопрос: http://forum.codenet.ru/showpost.php?p=298838&postcount=17
надеюсь теперь вы ответите на конкретно поставленый вопрос "почему так происходит?". В противном случае считаю ваши обвинения необоснованными.
Тебе же неоднократно уже ответили по существу, что код ужасный, и не известно, как он будет работать при разных входных значениях, т.к. в нем явная угроза stack overflow.
Что бы сказать детальнее, нужен тестовый пример с конкретным набором входных данных и эталонного результата.
P.S. Пока это напоминает картину: ты выуживаешь ноут из унитаза и требуешь объяснить, почему на ноутах не работает Windows XP ?
На что я неоднократно ответил - угроза есть, но дело не в ней.
построить любое двоичное дерево - это сложно? окей. вот вам эталоны:
входной файл содержит следующий текст:
0122233333444444444455555666667777777777777777777777777777778888888888888888888899999999999999999999
вывести коды Хаффмана для этого файла. Коды строить с помощью бинарного дерева.
вот правильный результат:
0 1111101
1 1111100
2 111111
3 11110
4 1110
5 1101
6 1100
7 10
8 01
9 00
вот НЕправильный результат:
0 1
1 10
2 111111
3 11110
4 1110
5 1
6 10
7 10
8 1
9 10
пока это напоминает картину трепа ни о чем. "причесаный" код отличается от моего лишь отсутствием кучи указателей и объединением вне передаваемых параметров. поправьте если я не прав, но это не должно влиять на выходной бинарник.
PS если кому-то лень строить дерево, я вышлю исходники на почту. заявки принимаю тут: light_soft[doggy]inbox[dot]ru
Ты откуда знаешь?
Доказательства в студию!
построить любое двоичное дерево - это сложно? окей. вот вам эталоны:
Не сложно. Но почему я (мы) должен(ы) делать работу, которую вполне в состоянии сделать ты сам?
А где тестовая программа? Тоже самим сделать?
Ты представляешь, как квалифицированные инженеры предоставляют информацию об ошибке?
Нужен тест, который воспроизводит баг.
Пока такого теста нет, ошибка не локализована. Раз ошибка не локализована, значит, виноват может быть кто угодно. Поэтому с такой же уверенностью можно утверждать, что баг вызван ураганом в Аризоне.
но это не должно влиять на выходной бинарник.
Ну в таком случае код вообще никак не влияет на бинарник... :D
PS если кому-то лень строить дерево, я вышлю исходники на почту. заявки принимаю тут: light_soft[doggy]inbox[dot]ru
Мне лень строить, лень и заявки писать. Может, нам ещё и в очередь на поклон выстроиться? :)
мил человек... я всегда поражался таким людям... тебе не лень писать толстенные сообщени _ни_о_чем_, которые ну никак еще мне не помогли приблизиться к решению вопроса.
но зато тебе лень чиркнуть 2 слова в мыло??
а может просто сказать нечего по существу?
или написание программы на указателях - это плохо? или этого не допускают стандарты?
покажи мне хоть фразу, хоть намек в стандартах, или учебниках по си(си++), которая запрещает передавать указатели в функцию и разыменовывать их внутри функции.
предугадывая вопросы "почему не запостить код сюда" - потому что есть несколько десятков лиц заинтересованных в этом коде(как бы криво он не был написан) - "студенты-одногруппники" называются.
но зато тебе лень чиркнуть 2 слова в мыло??
а может просто сказать нечего по существу?
или написание программы на указателях - это плохо? или этого не допускают стандарты?
покажи мне хоть фразу, хоть намек в стандартах, или учебниках по си(си++), которая запрещает передавать указатели в функцию и разыменовывать их внутри функции.
предугадывая вопросы "почему не запостить код сюда" - потому что есть несколько десятков лиц заинтересованных в этом коде(как бы криво он не был написан) - "студенты-одногруппники" называются.
Так запость пароленный архив, а ключег пошли в личку раз за свой копирайт боишсо, хотя за что там бояться в нете такого хоть чем жуй.
PS: Возиться с конем в вакууме никто не будет как и решать сию задачу ибо здесь свое время ценят.
мил человек... я всегда поражался таким людям...
Да и меня поражают паникеры, которые видят ошибки везде... в операционке, в компиляторе, в железе, но только не в своем чудо-коде.
Ты же не начал тему с того, что в твоем коде что-то не то...
А сразу заявил, что во всем виноват компилятор. :D
Ты случаем по монитору сверху не стучишь, как по старому телевизору, когда твоя программа выдает неверный результат? :D
тебе не лень писать толстенные сообщени _ни_о_чем_, которые ну никак еще мне не помогли приблизиться к решению вопроса.
Да ты просто не умеешь их читать.
Если бы ты хотя бы попытался проанализировать их, а не повторять постоянно "у меня все верно, это компилятор виноват", то возможно дело и сдвинулось бы у тебя с мертвой точки.
но зато тебе лень чиркнуть 2 слова в мыло??
Да лень + принцип.
За приватный танец я беру деньги... :)
а может просто сказать нечего по существу?
Тут говори, не говори... в глухие уши.
или написание программы на указателях - это плохо? или этого не допускают стандарты?
покажи мне хоть фразу, хоть намек в стандартах, или учебниках по си(си++), которая запрещает передавать указатели в функцию и разыменовывать их внутри функции.
М-да... а слона то ты и не заметил. При чем тут передача указателей?
предугадывая вопросы "почему не запостить код сюда" - потому что есть несколько десятков лиц заинтересованных в этом коде(как бы криво он не был написан) - "студенты-одногруппники" называются.
Так никто не просит тебя постить твой супер-идейный проект.
Локализуй ошибку, напиши тест воспроизводящий эту ошибку.
Может, пока пишешь тест и опыта понаберешься и претензии к компилятору отпадут сами собой.
PS: Возиться с конем в вакууме никто не будет как и решать сию задаю ибо здесь свое время ценят.
Да не нафег...
У нас тут открытый форум. А в ветке обсуждаются компиляторы.
Может доказать баг - пусть доказывает по всем правилам. Не может - в сад.
А решение курсовых - это отдельный раздел.
Да и для отдельной персоны стараться нет смысла.
Хочет привата - деньги в трусики.
P.S. +1 про коня
я смотрю тебе заявление про нормальную работу в 2008 студии тоже по барабану.
ты видать тоже не читаешь постов да? при том, что именно от изменения способа передачи объединенной строки меняется результат оптимизации, и как следствие - результат работы программы.
я смотрю тебе заявление про нормальную работу в 2008 студии тоже по барабану.
Представляешь, это только подтверждает подозрение о stackoverflow пока нет конкретных доказательств.
ты видать тоже не читаешь постов да? при том, что именно от изменения способа передачи объединенной строки меняется результат оптимизации, и как следствие - результат работы программы.
... но нет ни одного тестового примера
ДЛЯ ТЕХ, КТО В ТАНКЕ: ДАЛЬНЕЙШИЙ РАЗГОВОР БЕЗ ПРИМЕРА ВОСПРОИЗВОДЯЩЕГО БАГ - БЕССМЫСЛЕННЫЙ
жаль только, что те, кто в танке - не понимают, что они в танке. :D вот тут и получается stack overflow
Пока можно просто в отдельную тему в этом же разделе.
Может автор и осилит предоставить пример, тогда продолжим по существу.
Только сразу скажу: меня бесят утверждения, что нужно писать:
вместо
(и им подобные)
оба варианта синтаксически верны(и, как говорится, "попробуйте доказать обратное")
Оба варианта верны, второй вариант даже наглядней.
первый оптимальней, так false и есть 0, то запись
if (A) трактуется компилятором как if (false) при A=0 и if (true) при A>0
Во втором случае компилятор сначало сравнит значеия (если комилятор не оптимизирует этот участок кода)
PS: Нужно быть осторожным с автоматическим изменением типа, такие ошибки трудно находить к примеру: if(A=x)сначало A присвоет X, а потом Сравнит A равен ли 0, т.е условие ложно если x=0, Delphi бы ругался? а C++дает свободу для ошибок.
первый оптимальней, так false и есть 0, то запись
if (A) трактуется компилятором как if (false) при A=0 и if (true) при A>0
Во втором случае компилятор сначало сравнит значеия (если комилятор не оптимизирует этот участок кода)
чушь
PS: Нужно быть осторожным с автоматическим изменением типа, такие ошибки трудно находить к примеру: if(A=x)сначало A присвоет X, а потом Сравнит A равен ли 0, т.е условие ложно если x=0, Delphi бы ругался? а C++дает свободу для ошибок.
См. варниги!
{
char n[256] = "";
strcpy(n, c);
if ((*node).top != NULL)
{
createCodes((*node).top, strcat(n, "1"), codes);
} else {
strcat(codes[(*node).topVal], strcat(n, "1"));
}
strcpy(n, c);
if ((*node).bottom != NULL)
{
createCodes((*node).bottom, strcat(n, "0"), codes);
} else {
strcat(codes[(*node).bottomVal], strcat(n, "0"));
}
}
оптимизируется 6 студией неверно(причем именно по скорости если оптимизировать).
Сам проверить утверждение пока не берусь, с плюсами еще на "Вы" (до этого 2 года писал на Delphi без углубления в отладку и ассемблер).
Сейчас просто вынужден разбираться в С/C++ и асме(программа ВУЗа).
Опишите структуру Node