LINUX.ORG.RU

Доводить до минимума приведение типов (minimize casting) в C++


0

0

"Правила C++ составлены так, чтобы гарантировать невозможность ошибок, связанных с типами. В теории, если программа скомпилируется без ошибок, она не попытается выполнить каких-либо небезопасных или нелепых действий над каким-либо объектом. Эта гарантия очень ценна."

>>> Статья

★★★★

Проверено: Pi ()

Ответ на: комментарий от mikhail

>Зато переполнения буфера на каждом углу.

Пишите по-человечески, на STL / Boost С++, а не на смести K&R + C++ и переполнений не будет.

stellar
()
Ответ на: комментарий от anonymous

>Зато будут фирменные крестовые тормоза. Нет уж, жаба лучше.

Красноглазый, ты сначала спецификацию на std::vector / std::string почитай, на счет operator[].

И вообще, бенчмарки для контейнерных классов Java / C++ в студию! :))

stellar
()
Ответ на: комментарий от BastardOperatorFromHell

>Если вместо char* использовать std::string, а вместо int[] или double[] истользовать vector<int> или vector<double>, то никаких переполнений буфера не будет.

Будут, будут. Проверяется только функция "at". Правда, насколько мне известно, STLPort в режиме отладки также проверяет и оператор [].

WFrag ★★★★
()

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

Статья для карапузов. Даже не раскрыты правила по которым определяется какому new-style cast'у соответствует old-style cast.

dilmah ★★★★★
()
Ответ на: комментарий от mikhail

>Зато переполнения буфера на каждом углу

Миша, что-то тебя не часто можно увидеть в Development форуме. Я не знал, что та специалист по методологии программирования. Какой именно буфер у тебя на каждом углу переполняется? Что вообще за буферы на С++? Учи stl и не будет ни тормозов ни переполнений. PS: И заведи девушку накоц, будешь не только о "буферах" думать.

devinull ★★
()
Ответ на: комментарий от stellar

Хм... а почему не писать на смеси? Я вот пишу и переполнений нет и все нормально. STL/Boost - это хорошо, но "хорошая вешь" (как доказала история, причем не однократно) в одних руках - "зло", в других - "добро".

Не так все гладко с шаблонами, и еще одни момент - производительность. Ее еще никто не отменял. :)

anonymous
()
Ответ на: комментарий от Sun-ch

Когда они у девушки переполнятся - будет уже поздно :))

anonymous
()
Ответ на: комментарий от WFrag

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

Мне вот одно не понятно, почему он там ругался на преобразование int в double? Просто размер int = 4 байта (берем ПК), размер double = 8 байт, то преобразование будет проведено нормально, вот обратное double в int - это проблемно...

anonymous
()
Ответ на: комментарий от anonymous

> Мне вот одно не понятно, почему он там ругался на преобразование int в double? Просто размер int = 4 байта (берем ПК), размер double = 8 байт, то преобразование будет проведено нормально, вот обратное double в int - это проблемно...

он не ругался, он обратил внимание что это будет некая нетривиальная рантайм операция. Потом, при приведении int->double запросто может быть потеря точности. Карапузы должны благодарить IEEE754 за то что она спасает для маленьких целых.

dilmah ★★★★★
()
Ответ на: комментарий от anonymous

IMHO Ругался он потому, что double = (double)(int/int) double = (((double)(int))/int) дадут разный результат(в первом случае округление до целого).

YesSSS ★★★
()
Ответ на: комментарий от anonymous

> и еще одни момент - производительность

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

std::sort рвет qsort например.

anonymous
()

Луговский! Профессор! Где ты? Выходи, без тебя скучно. :(

"Автору С++ место в дурке или на погосте" (с)

anonymous
()
Ответ на: комментарий от anonymous

Переполнение буфера.. ржунемогу. Откуда же у вас руки растут? Автор статьи - молодец, но уровень читателей для неё - newbie in C++.

anonymous
()

> В теории, если программа скомпилируется без ошибок, она не попытается выполнить каких-либо небезопасных или нелепых действий над каким-либо объектом. Эта гарантия очень ценна.

В том-то и дело, что только в теории. На практике, если ты в какм-нибудь классе перегрузил оператор new, delete или operator=(), то ты взял на себя всю ответственность за управление памятью. Тут компилятор умывает руки. Так что не стоит притуплять бдительность программистов подобными заявлениями. Да, С++ - язык со строгой типизацией, но если программист берется за управление памятью для своих типов данных, то на компилятор надеяться не стоит.

mutronix ★★★★
()
Ответ на: комментарий от anonymous

> Чо читать-то. Это же очевидно.

К сожалению не всем. Тебя бы инфаркт хватил при виде плюсового кода, порожденного "опытным пхпшником".

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от Selecter

Полностью согласен! Еще бы про алгоритмы их анализ и поведение! Было бы ваще супер!!! :)

anonymous
()

Свистёж. Система типов в C++ дырява, так что гарантии никакой НЕТ. Сравнивать с ML-ом или хотя бы с Адой.

anonymous
()
Ответ на: комментарий от anonymous

>std::sort рвет qsort например.

#include <cstdlib> #include <iostream> #include <vector>

using namespace std;

const unsigned long M = 0xFFFFFF;

int cmp(const void* a,const void* b) { if (*(int*)a == *(int*)b) return 0; if (*(int*)a > *(int*)b) return 1; else return -1; }

int main() { srand(time(0)); int* buf0 = new int[M]; vector<int> buf1(M); for (int i = 0; i < M; i++) buf1[i] = buf0[i] = rand(); cout << "\n"; time_t begin,end; begin = time(0); qsort((void*)buf0,M,sizeof(buf0),cmp); end = time(0); cout << "qsort:\t" << end - begin << "\n"; begin = time(0); sort(buf1.begin(),buf1.end()); end = time(0); cout << "std::sort:\t" << end - begin << "\n"; delete [] buf0; return 0; }

./project1 qsort: 7 std::sort: 15

anonymous
()
Ответ на: комментарий от anonymous

#include <cstdlib>

#include <iostream>

#include <vector>

using namespace std;

const unsigned long M = 0xFFFFFF;

int cmp(const void* a,const void* b)

{

if (*(int*)a == *(int*)b)

return 0;

if (*(int*)a > *(int*)b)

return 1;

else return -1;

}

int main()

{

srand(time(0));

int* buf0 = new int[M];

vector<int> buf1(M);

for (int i = 0; i < M; i++)

buf1[i] = buf0[i] = rand();

cout << "\n";

time_t begin,end;

begin = time(0);

qsort((void*)buf0,M,sizeof(buf0),cmp);

end = time(0);

cout << "qsort:\t" << end - begin << "\n";

begin = time(0);

sort(buf1.begin(),buf1.end());

end = time(0);

cout << "std::sort:\t" << end - begin << "\n";

delete [] buf0;

return 0;

}

./project1

qsort: 7

std::sort: 15

anonymous
()
Ответ на: комментарий от anonymous

> почитай малыш книжки по C++, посмотри как реализованы шаблоны в компиляторе, а потом говори про производительность.

> std::sort рвет qsort например.

Это она только в книжках и в теории рвёт.

Я как-то посмотрел что за код генерится для

std::valarray<double> a = b + c;

где b и c - тоже valarray. Душераздирающее зрелище :(( Нахера-то создаются 2 временных массива :(((( Чуть лучше выглядел код для

std::valarray<double> a(b + c);

только 1 временный массив. Дело было, правда, давно - в 2000 году, компилер - последний Борландовский на то время.

pitekantrop ★★★
()
Ответ на: комментарий от BastardOperatorFromHell

> Если вместо char* использовать std::string, а вместо int[] или double[] истользовать vector<int> или vector<double>, то никаких переполнений буфера не будет.

Их не будет, если вместо C++ использовать Ocaml, плюс получите нормальную систему типов.

anonymous
()
Ответ на: комментарий от anonymous

Да не будет переполнений, если при написании кода голову включать!!! А дашь дураку стеклянный x@й так он, либо про@бет, либо разобьет! Не зависимо от языка - ошибок можно наделать везьде.

anonymous
()
Ответ на: комментарий от anonymous

>$ g++ -O2 test.c >$ ./a.out

>qsort: 15 >std::sort: 5

>$ gcc --version >gcc (GCC) 3.2.3

$g++ -O2 main.cpp -o main

$./main

$qsort: 7 $std::sort: 4

$gcc --version gcc (GCC) 3.4.2

-02 -вот блин я лоханулся.

anonymous
()
Ответ на: комментарий от anonymous

> ./project1 > qsort: 7 > std::sort: 15

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

[bogerm@gw test]$ g++ -O3 -o project1 project1.cpp [bogerm@gw test]$ ./project1

qsort: 9 std::sort: 3

Bogerm
()
Ответ на: комментарий от anonymous

я же говорю: алгоритмы сортировки - они зависимы от данных! qsort - он будет проигрывать на больших объемах данных (< 100000 элементов), на маленьких - он будет выигрывать! В зависимости от объема данных - надо и выбирать соответствующий алгоритм!

Сравните данные при M=0xFFFFF; - и получите соответствующие результаты!!!

anonymous
()
Ответ на: комментарий от Bogerm

>Забавные результаты у тебя получаются, у меня все как в теории:

Д я просто лоханулся без -O2(3)

anonymous
()
Ответ на: комментарий от aton

не будет! это все из-за перестановок! вот почитай описание http://algolist.manual.ru/sort/quick_sort.php и попробуй рассмотреть наихудший и наилучший случай. потом попробуй посчитать в зависимости от элементов. и сравни с тем же алгоритмом шелла.

anonymous
()
Ответ на: комментарий от Sun-ch

>А это правда, что ошибка приведения типов в Аде - была самой дорогой в истории человечества?

Ложь.

anonymous
()
Ответ на: комментарий от svu

Ну и ... ??? Дальше то что? Это типа один дурак долго-долго трахался чтобы снять со своей тачки тормоза, причем на каждой открученной детальке было написано крупными красными буквами "НЕ ДЕЛАЙ ЭТОГО - РАЗОБЬЕШСЯ!", наконец снял, разогнался и вылетел на первом же повороте, а народ кругом - ну мля и машины пошли нынче! Ошибка в тормозной системе стоила пацану жизни! КАРАУЛ!  


anonymous
()
Ответ на: комментарий от svu

Ну а если говорить серьезно - ошибка была в модели, о чем и говорят уважаемый товарисч Prof. J. L. LIONS. Одно печально - ошибки в ДНК Ada распознавать еще и не научилась.

anonymous
()
Ответ на: комментарий от pitekantrop

> Я как-то посмотрел что за код генерится для

> std::valarray<double> a = b + c;

> где b и c - тоже valarray. Душераздирающее зрелище :(( 
> Нахера-то создаются 2 временных массива :((((

Реализация valarray у всех известных мне вариантов STL(включая
GCC'шную) действительно отвратная. Отсюда следует только то, что
надо пользовать правильные библиотеки -- blitz++, daixtrose, tvmet
и иже с ними, а не "C++ -- тормоз".

$ cat addvec.cpp

#include <iostream>
#include <tvmet/Vector.h>

typedef tvmet::Vector<double, 3> Vec3;

void doit(const Vec3& a, const Vec3& b, Vec3& c)
{
	c = a + b;
}

int main(int argc, char** argv)
{
	Vec3 a, b, c;
	a = 1.0, 2.0, 3.0;
	b = 3.0, 2.0, 1.0;
	doit(a, b, c);
	return 0;
}

$ g++ -O2 -march=pentium4 -msse2 -ffast-math -mfpmath=sse -finline-limit=1500 -funroll-loops -fomit-frame-pointer -o addvec addvec.cpp
$ gdb --silent ./addvec 
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disassemble doit
Dump of assembler code for function _Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_:
0x08048558 <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+0>:  mov    0x4(%esp),%eax
0x0804855c <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+4>:  mov    0x8(%esp),%edx
0x08048560 <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+8>:  mov    0xc(%esp),%ecx
0x08048564 <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+12>: movsd  (%eax),%xmm0
0x08048568 <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+16>: addsd  (%edx),%xmm0
0x0804856c <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+20>: movsd  %xmm0,(%ecx)
0x08048570 <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+24>: movsd  0x8(%eax),%xmm0
0x08048575 <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+29>: addsd  0x8(%edx),%xmm0
0x0804857a <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+34>: movsd  %xmm0,0x8(%ecx)
0x0804857f <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+39>: movsd  0x10(%eax),%xmm0
0x08048584 <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+44>: addsd  0x10(%edx),%xmm0
0x08048589 <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+49>: movsd  %xmm0,0x10(%ecx)
0x0804858e <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+54>: ret    
0x0804858f <_Z4doitRKN5tvmet6VectorIdLj3EEES3_RS1_+55>: nop    
End of assembler dump.

IMHO, вполне сойдет.

$ g++ --version
g++ (GCC) 4.0.1 (Debian 4.0.1-1)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Dselect ★★★
()

> Правила C++ составлены так, чтобы гарантировать невозможность ошибок, связанных с типами.

А я и не знал, что по%@отина с _автоматическим_ преобразованием
int в double и проч. существует именно для того, чтобы "гарантировать
невозможность ошибок, связанных с типами". Про RTTI вообще молчу...

Dselect ★★★
()
Ответ на: комментарий от anonymous

> int cmp(const void* a,const void* b) { if (*(int*)a == *(int*)b) return 0; if (*(int*)a > *(int*)b) return 1; else return -1; }

В C/C++ есть замечательное условное выражение...

int cmp(const void* a,const void* b) { int i = *(int*)a, j = *(int*)b;

return i == j ? 0 : i > j ? 1 : -1; }

anonymous
()
Ответ на: комментарий от Bogerm

> qsort: 9 std::sort: 3

g++ (GCC) 4.0.1 (Debian 4.0.1-2), Pentium MMX 200 MHz:

g++ project1.cpp даёт: qsort: 124 std::sort: 156

g++ -O2 project1.cpp даёт: qsort: 100 std::sort: 27

g++ -O3 project1.cpp даёт: qsort: 100 std::sort: 26

anonymous
()
Ответ на: комментарий от anonymous

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

Переписал на STL, там использовался deque из struct { double x, y; } стала считать 90 секунд, попробовал заменить математику на SSE2 считала примерно столько же, начал рыть ASM, меня просто ПОРАЗИЛ код математики gcc - с оптимиазцией почти как человек на асме.

Потом, переписал STL deque на свой из пары векторов double *x, *y чтобы можно было линейно грузить в SSE2 регистры. С SSE кодом (рукописный ASM) стала считать 14 секунд, без SSE (только оптимизация компилера) 19.

Потом, совершенно случайно, откопали в инете математику похожую на нашу, и слава маткаду, получилось заменить алгоритм O(k*n*n) на O(k*n), стала считать 2 секунды БЕЗ SSE, собственно отпала необходимость в SSE совсем.

Еще раз доказано, что оптимизация железом и асмом дает прирост производительности в разы, а алгоритмом - на порядки.

anonymous
()
Ответ на: комментарий от anonymous

> К сожалению не всем. Тебя бы инфаркт хватил при виде плюсового кода, порожденного "опытным пхпшником".
Я видел жабский код, написанный "опытным дельпхистом". Это да-а-а, это зачет. 8-)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.