Здравствуйте, Трурль, Вы писали:
Т>Здравствуйте, CrystaX, Вы писали:
AVC>>>Между Обероном-языком и Обероном-средой (и Обероном-системой) есть связь. CX>>Но мы ведь говорим об Обероне-языке, а не об Обероне-системе?
Т>Без знакомства с Оберон-системой Оберон как язык не производит должного впечатления. Так же, как и Smalltalk, Java или C#. Представьте любой из этих языков как средство разработки на голом Win(Unix)Api.
Я как раз на днях ознакомился с Оберон-системой (Blackbox). Не скажу, что мое восприятие языка от этого изменилось. Впрочем, поживем — увидим.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[39]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, CrystaX, Вы писали:
CX>Я как раз на днях ознакомился с Оберон-системой (Blackbox). Не скажу, что мое восприятие языка от этого изменилось. Впрочем, поживем — увидим.
Blackbox – несколько не то. Там своя философия, ближе к ОО-мейнстриму. Не стану утверждать, что он хуже чем Оберон но, во всяком случае, не столь своеобразен.
Например, в Обероне нет методов. Его за это в свое время много критиковали и вынудили таки добавить в Оберон-2 "процедуры, связанные с типами". Между тем, Вирт не стал включать методы в язык, потому что они не понадобились при разработке системы.
Re[40]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, Трурль, Вы писали:
CX>>Я как раз на днях ознакомился с Оберон-системой (Blackbox). Не скажу, что мое восприятие языка от этого изменилось. Впрочем, поживем — увидим.
Т>Blackbox – несколько не то. Там своя философия, ближе к ОО-мейнстриму. Не стану утверждать, что он хуже чем Оберон но, во всяком случае, не столь своеобразен. Т>Например, в Обероне нет методов. Его за это в свое время много критиковали и вынудили таки добавить в Оберон-2 "процедуры, связанные с типами". Между тем, Вирт не стал включать методы в язык, потому что они не понадобились при разработке системы.
Ок. На что, в таком случае, Вы посоветовали бы обратить внимание?
Здравствуйте, eao197, Вы писали:
E>Что-то в этой ветке часто упоминается, что есть языки, в которых выход за пределы массива четко и точно отлавливается в run-time. И говорится, что это круто, и что из-за отсутствия таковой возможности C/C++ must die!
Насчет C/C++ must die — как говорится, no comments, потому как комментироват чушь не хочется.
А вот насчет того, что есть языки с контролем выхода за пределы массива — не надо никакой Java/Oberon, это еще Turbo Pascal умел. Разумееется, для массивов описанных статически. И кстати, Compaq Fortran умеет , недавно сам убедился.
А вообще не слишком ли много уделяется внимания такой, в общем-то , несложной проблеме, как выход за пределы индекса ? Дело даже не в том, что это обычно не перехватывают. Дело в том, что типов ошибок море, и в большинстве случаев компилятор/среда помочь в их отлавливании не может. Ну, к примеру, плюс вместо минуса поставил или не ту переменную употребил. Если такие ошибки остались в программе — значит, она плохо оттестирована. Вот и все. И выход индекса — лишь одна из таких ошибок. А при отладке банальный ASSERT поможет эту ошибку найти.
With best regards
Pavel Dvorkin
Re[2]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А вот насчет того, что есть языки с контролем выхода за пределы массива — не надо никакой Java/Oberon, это еще Turbo Pascal умел. Разумееется, для массивов описанных статически.
А почему, собственно, "разумеется"?
Оберон и с динамическими многомерными массивами прекрасно справляется.
PD>А вообще не слишком ли много уделяется внимания такой, в общем-то , несложной проблеме, как выход за пределы индекса ?
Дело не только в выходе за пределы массива.
Практически вся работа с памятью в Си/Си++ ведется опасными средствами.
PD>Дело даже не в том, что это обычно не перехватывают. Дело в том, что типов ошибок море, и в большинстве случаев компилятор/среда помочь в их отлавливании не может. Ну, к примеру, плюс вместо минуса поставил или не ту переменную употребил. Если такие ошибки остались в программе — значит, она плохо оттестирована. Вот и все. И выход индекса — лишь одна из таких ошибок. А при отладке банальный ASSERT поможет эту ошибку найти.
Если бы с проблемами Си/Си++ можно было справиться банальными ASSERT!
Кто бы стал критиковать такой замечательный язык!
Но, увы, это не так. Не верите мне, спросите других Си++программистов, какими средствами они добиваются надежности своих программ. Почти всегда это весьма изобретательные и остроумные, но натужные решения простых, в общем-то, проблем.
А что касается конкретной Вашей рекомендации (ASSERT), то ничего против нее не имею.
Но только (по крайней мере, в чистом виде) не выручит она Вас в случае с массивом. Ведь массив в Си/Си++ в качестве параметра синтаксически неотличим от указателя (т.е. и есть указатель). Чем же поможет Вам ASSERT применительно к указателю, просто указателю?
А вообще-то, у нас здесь языковой флейм потихоньку (не все сразу ) сходит "на нет".
Оказывается, можем мы все-таки понимать друг друга.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[3]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, AVC, Вы писали:
AVC>Но только (по крайней мере, в чистом виде) не выручит она Вас в случае с массивом. Ведь массив в Си/Си++ в качестве параметра синтаксически неотличим от указателя (т.е. и есть указатель). Чем же поможет Вам ASSERT применительно к указателю, просто указателю?
Вообще-то в C++ указатель и массив — это разные вещи!
AVC>А вообще-то, у нас здесь языковой флейм потихоньку (не все сразу ) сходит "на нет". AVC>Оказывается, можем мы все-таки понимать друг друга.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[4]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, CrystaX, Вы писали:
AVC>>Но только (по крайней мере, в чистом виде) не выручит она Вас в случае с массивом. Ведь массив в Си/Си++ в качестве параметра синтаксически неотличим от указателя (т.е. и есть указатель). Чем же поможет Вам ASSERT применительно к указателю, просто указателю?
CX>Вообще-то в C++ указатель и массив — это разные вещи!
В области видимости (scope) массива — несомненно.
Но при передаче массива в качестве параметра в другую функцию — уже нет.
Пример:
#include <cstdio>
#include <cassert>
void foo(int *p)
{
assert(p != NULL); // для начала, перекрестясь, подстрахуемся с помощью assert; авось, поможет!
// здесь какой-то код, работающий то ли с массивом, то ли с указателем.
printf("%d\n", p[1023]); // например, так; ах, я кажется вышел за границу массива... но откуда мне было знать?delete p; // или так; ой, я "удалил" стековую переменную... какой все-таки Си++ сложный! :)
}
int main()
{
int a[10]; // массивint *p; // указатель;
foo(a); // передаем массив
p = new int;
foo(p); // передаем указатель на int
p = new int[10];
foo(p); // передаем указатель (или все-таки массив? :) )return 0;
}
В Обероне (и не только), напротив, массив — всегда массив.
(Это что-то из детства:
Недаром люди говорят:
Солдат — всегда солдат!
)
Например:
PROCEDURE foo(VAR p: ARRAY OF INTEGER);
VAR i: LONGINT;
BEGIN
FOR i := 0 TO LEN(p)-1 DO
Out.Int(p[i], 0); Out.Ln; (* совершенно безопасно *)END:
p := NIL; (* ошибка компиляции *)
NEW(p); (* ошибка компиляции *)END foo;
Разумеется, я привел эти шуточные примеры не для того, чтобы доказать, что Си++ — "плох", а Оберон — "хорош".
Надеюсь, мы все-таки переросли эту детскую "болезнь левизны".
Я только хотел проиллюстрировать свое утверждение о неотличимости (иногда) в Си/Си++ массива от указателя.
AVC>>А вообще-то, у нас здесь языковой флейм потихоньку (не все сразу ) сходит "на нет". AVC>>Оказывается, можем мы все-таки понимать друг друга.
CX>
Взаимно!
Надеюсь скоро "родить" пост о проблемах надежности ПО.
Все как-то не хватает — то времени, то сосредоточенности...
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[5]: Что толку в Ада если Ариан 5 все равно упал
Может, перейдем на ты? Удобнее, да и форуму соответствует.
AVC>В области видимости (scope) массива — несомненно. AVC>Но при передаче массива в качестве параметра в другую функцию — уже нет. AVC>Пример:
[skipped]
А теперь попробуй так:
#include <cstdio>
#include <cassert>
template <size_t N>
void foo(int (&p)[N])
{
assert(p != NULL); // для начала, перекрестясь, подстрахуемся с помощью assert; авось, поможет!
// здесь какой-то код, работающий то ли с массивом, то ли с указателем.
printf("%d\n", p[1023]); // например, так; ах, я кажется вышел за границу массива... но откуда мне было знать?delete p; // или так; ой, я "удалил" стековую переменную... какой все-таки Си++ сложный! :)
}
int main()
{
int a[10]; // массивint *p; // указатель;
foo(a); // передаем массив
p = new int;
foo(p); // передаем указатель на int
p = new int[10];
foo(p); // передаем указатель (или все-таки массив? :) )return 0;
}
И попробуй скомпилировать это нормальным компилятором (Comeau C++ online подойдет). Узнаешь много нового
AVC>Разумеется, я привел эти шуточные примеры не для того, чтобы доказать, что Си++ — "плох", а Оберон — "хорош". AVC>Надеюсь, мы все-таки переросли эту детскую "болезнь левизны". AVC>Я только хотел проиллюстрировать свое утверждение о неотличимости (иногда) в Си/Си++ массива от указателя.
В данном случае ты воспользовался автоматическим приведением массива к указателю (array-to-pointer conversion), поэтому сетовать можешь только на себя. Кстати, это еще один довод в пользу неиспользования голых указателей. В случае, если бы там был смарт-пойнтер, даже этой проблемы не было бы.
AVC>>>А вообще-то, у нас здесь языковой флейм потихоньку (не все сразу ) сходит "на нет". AVC>>>Оказывается, можем мы все-таки понимать друг друга.
CX>>
AVC>Взаимно! AVC>Надеюсь скоро "родить" пост о проблемах надежности ПО. AVC>Все как-то не хватает — то времени, то сосредоточенности...
Ничего страшного, времени у нас достаточно.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[6]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, CrystaX, Вы писали:
CX>Может, перейдем на ты? Удобнее, да и форуму соответствует.
С удовольствием.
Да и то правда — какое там "Вы", когда Ариан-5 все-таки упал!
AVC>>В области видимости (scope) массива — несомненно. AVC>>Но при передаче массива в качестве параметра в другую функцию — уже нет. AVC>>Пример: CX>[skipped]
CX>А теперь попробуй так:
CX>
CX>#include <cstdio>
CX>#include <cassert>
CX>template <size_t N>
CX>void foo(int (&p)[N])
CX>{
CX> assert(p != NULL); // для начала, перекрестясь, подстрахуемся с помощью assert; авось, поможет!
CX> // здесь какой-то код, работающий то ли с массивом, то ли с указателем.
CX> printf("%d\n", p[1023]); // например, так; ах, я кажется вышел за границу массива... но откуда мне было знать?
CX> delete p; // или так; ой, я "удалил" стековую переменную... какой все-таки Си++ сложный! :)
CX>}
CX>int main()
CX>{
CX> int a[10]; // массив
CX> int *p; // указатель;
CX> foo(a); // передаем массив
CX> p = new int;
CX> foo(p); // передаем указатель на int
CX> p = new int[10];
CX> foo(p); // передаем указатель (или все-таки массив? :) )
CX> return 0;
CX>}
CX>
CX>И попробуй скомпилировать это нормальным компилятором (Comeau C++ online подойдет). Узнаешь много нового
Стыжусь, но я действительно этого не знал!
Comeau C++ online не потребовался — уже второй домашний компилятор Си++ (GNU C++) с этим справился.
К сожалению, код
p = new int[10];
foo(p); // передаем указатель (или все-таки массив? :) )
так и не скомпилировался. А ведь вроде бы — чем не массив?
У меня по ходу дела два вопроса.
1) Почему здесь все знатоки Си++ ссылаются, как правило, на Comeau C++?
(Помню, этим меня удивил еще Павел Кузнецов.)
Comeau C++ особенно продвинут? Или здесь важнее его доступность online?
2) Не растет ли в данном случае размер кода, если foo вызывается с массивами разной размерности?
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[7]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, AVC, Вы писали:
AVC>К сожалению, код AVC>
AVC> p = new int[10];
AVC> foo(p); // передаем указатель (или все-таки массив? :) )
AVC>
AVC>так и не скомпилировался. А ведь вроде бы — чем не массив?
Э, батенька! Указатель на массив и массив — это разные вещи. Это ещё Сергей Губанов разъяснял!
AVC>У меня по ходу дела два вопроса. AVC>1) Почему здесь все знатоки Си++ ссылаются, как правило, на Comeau C++? AVC>(Помню, этим меня удивил еще Павел Кузнецов.) AVC>Comeau C++ особенно продвинут? Или здесь важнее его доступность online?
Один из наиболее соответвтвующих Стандарту компиляторов. (Хотя тоже есть бажки, но, в отличие от MS, он не занимается обратной совместимостью с хреновыми предшественниками).
Ну и онлайновость — приятный бонус.
AVC>2) Не растет ли в данном случае размер кода, если foo вызывается с массивами разной размерности?
Вообще говоря, если попрактиковать жёсткую типизацию, то проблем не будет.
template<class T>
class array_t
{
typedef T* iterator; // кому хочется - прикручивайте онлайновые проверки
size_t size() const { return e_-b_; }
iterator begin() const { return b_; }
iterator end() const { return e_; }
array_t(T* b, T* e) : b_(b), e_(e) { assert(b && e && b<=e); }
template<int N>
array_t(T (&arr)[N]) : b_(arr), e_(arr+N) {}
private:
T *b_, *e_; // наследие Си - массив как указатель - тщательно спрятано
};
template<class T>
array_t<T> array(T* arr, int N) { return array_t<T>(arr,arr+N); } // для явного приведения; пользоваться только в случае крайней нужды!template<class T>
array_t<T> array(T* arr, T* end) { return array_t<T>(arr,end); } // для явного приведения; пользоваться только в случае крайней нужды!template<class T>
array_t<T> new_array(size_t n) { T* arr=new T[n]; return array_t<T>(arr,arr+N); } // создавать динамически? извольте-сtemplate<class T>
void delete_array(array_t<T> arr) { delete[] arr.begin(); } // ну там френды-шменды, разумеется. Не так уж влобvoid foo(array_t<int> arr); // это нешаблонная функцияint main()
{
int x[10];
int* y = x; // бардак-с! тяжкое legacy наследие
array_t<int> z = new_array(10);
foo(x);
foo(array(y,10));
foo(z);
delete_array(z); // это мы по-простому, без умных указателей.
}
Перекуём баги на фичи!
Re[8]: Что толку в Ада если Ариан 5 все равно упал
Понятно, что такие изыски — это заделывание дыр, оставшихся от голого Си.
Типы и конструкции типов, которые в других языках встроены в синтаксис, можно/нужно воспроизвести в виде шаблонов классов.
По сути, разработчик шаблонной библиотеки повторяет работу, которую делает разработчик компилятора другого языка.
Кроме того, разработчик шаблонной библиотеки делает шлюзы для совместимости с примитивными типами (массивами, массивами как указателями, строками как массивами, строками как указателями) — чтобы можно было состыковывать с литералами и с legacy-кодом.
(Если бы std::string не имел конвертора из const char*, было бы сущее мучение создавать строки; как, впрочем, и набивать строковый литерал в виде массива символов).
Перекуём баги на фичи!
Re[8]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, Кодт, Вы писали:
AVC>>К сожалению, код AVC>>
AVC>> p = new int[10];
AVC>> foo(p); // передаем указатель (или все-таки массив? :) )
AVC>>
AVC>>так и не скомпилировался. А ведь вроде бы — чем не массив?
К>Э, батенька! Указатель на массив и массив — это разные вещи. Это ещё Сергей Губанов разъяснял!
А есть способ создать указатель на массив в динамической памяти, не прибегая к явному приведению типа?
int (*p)[10] = ((*)[10]) new int[10]; // радует также возможность употребить одну и ту же константу трижды :)
Посмотрим, решает ли все проблемы введение указателя на массив.
Допустим, я хочу вызвать упомянутую процедуру foo
PROCEDURE foo(a: ARRAY OF INTEGER);
BEGIN
END foo;
из обероновского кода, передав в качестве параметра открытый массив, расположенный в куче.
Все просто:
PROCEDURE test_foo(size: INTEGER);
VAR a: ARRAY 10 OF INTEGER;
p: POINTER TO ARRAY OF INTEGER; (* указатель на открытый массив *)BEGIN
foo(a); (* все хорошо *)
NEW(p, size); (* создаем массив заранее неизвестного размера *)
foo(p^); (* все еще лучше :) *)END test_foo;
Здесь нет никаких проблем, причем в любом случае массив остается массивом.
А что же с попыткой передать в функцию
template <size_t N>
void foo(int (&p)[N])
{
}
открытый массив, расположенный в динамической памяти, не прибегая к новым темплитам и/или классам?
Сделаем по аналогии с Обероном (хотя все-таки потребуется явное приведение типа):
void test_foo(size_t size)
{
int a[10];
int (*p)[size] = (int (*)[size]) new int[size];
foo(a);
// пока все хорошо
foo(*p); // а здесь у меня случился кряк: внутренняя ошибка компилятора 243
}
Ай, получил сообщение компилятора (GNU C++):
Internal compiler error 243.
К чему бы это? Наверное, к дождю. Уже голова болит от того, что даже такая мелочь здесь проблема.
Может, какому-нибудь компилятору Си++ (например, Comeau C++) повезло бы здесь больше? Но выяснить это уже нет сил.
AVC>>У меня по ходу дела два вопроса. AVC>>1) Почему здесь все знатоки Си++ ссылаются, как правило, на Comeau C++? AVC>>(Помню, этим меня удивил еще Павел Кузнецов.) AVC>>Comeau C++ особенно продвинут? Или здесь важнее его доступность online?
К>Один из наиболее соответвтвующих Стандарту компиляторов. (Хотя тоже есть бажки, но, в отличие от MS, он не занимается обратной совместимостью с хреновыми предшественниками). К>Ну и онлайновость — приятный бонус.
Спасибо за информацию!
А что касается "совместимости с хреновыми предшественниками", то разве только MS этим занимается?
Да весь Си++ на этом выстроен, как Петербург на болоте!
AVC>>2) Не растет ли в данном случае размер кода, если foo вызывается с массивами разной размерности?
К>Вообще говоря, если попрактиковать жёсткую типизацию, то проблем не будет. К>
К>template<class T>
К>class array_t
К>{
К> typedef T* iterator; // кому хочется - прикручивайте онлайновые проверки
К> size_t size() const { return e_-b_; }
К> iterator begin() const { return b_; }
К> iterator end() const { return e_; }
К> array_t(T* b, T* e) : b_(b), e_(e) { assert(b && e && b<=e); }
К> template<int N>
К> array_t(T (&arr)[N]) : b_(arr), e_(arr+N) {}
К>private:
К> T *b_, *e_; // наследие Си - массив как указатель - тщательно спрятано
К>};
К>template<class T>
К>array_t<T> array(T* arr, int N) { return array_t<T>(arr,arr+N); } // для явного приведения; пользоваться только в случае крайней нужды!
К>template<class T>
К>array_t<T> array(T* arr, T* end) { return array_t<T>(arr,end); } // для явного приведения; пользоваться только в случае крайней нужды!
К>template<class T>
К>array_t<T> new_array(size_t n) { T* arr=new T[n]; return array_t<T>(arr,arr+N); } // создавать динамически? извольте-с
К>template<class T>
К>void delete_array(array_t<T> arr) { delete[] arr.begin(); } // ну там френды-шменды, разумеется. Не так уж влоб
К>void foo(array_t<int> arr); // это нешаблонная функция
К>int main()
К>{
К> int x[10];
К> int* y = x; // бардак-с! тяжкое legacy наследие
К> array_t<int> z = new_array(10);
К> foo(x);
К> foo(array(y,10));
К> foo(z);
К> delete_array(z); // это мы по-простому, без умных указателей.
К>}
К>
Как говорила девочка из одной книжки: "Все чудесатее и чудесатее!"
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[3]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, AVC, Вы писали:
AVC>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>А вот насчет того, что есть языки с контролем выхода за пределы массива — не надо никакой Java/Oberon, это еще Turbo Pascal умел. Разумееется, для массивов описанных статически.
AVC>А почему, собственно, "разумеется"? AVC>Оберон и с динамическими многомерными массивами прекрасно справляется.
"Разумеется" относится к Турбо Паскалю.
AVC>Дело не только в выходе за пределы массива. AVC>Практически вся работа с памятью в Си/Си++ ведется опасными средствами.
Именно благодаря этому код на C/C++ столь эффективен.
AVC>А что касается конкретной Вашей рекомендации (ASSERT), то ничего против нее не имею. AVC>Но только (по крайней мере, в чистом виде) не выручит она Вас в случае с массивом. Ведь массив в Си/Си++ в качестве параметра синтаксически неотличим от указателя (т.е. и есть указатель). Чем же поможет Вам ASSERT применительно к указателю, просто указателю?
К просто указателю — ничем. Но если он (я это знаю) показывает на область памяти, которую я рассматриваю как массив, то он поможет, так как размер мне известен, а указатель всегда индексируется. Проверьте индекс, и все дела.
Если же указатель показывает не на массив, то индексы здесь ни при чем.
With best regards
Pavel Dvorkin
Re[9]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, AVC, Вы писали:
AVC>К чему бы это? Наверное, к дождю. Уже голова болит от того, что даже такая мелочь здесь проблема. AVC>Как говорила девочка из одной книжки: "Все чудесатее и чудесатее!"
Алексей, помнишь: "Это не дурдом, это особенность"
Просто для того, чтобы не забивать себе голову такими проблемами, нужно использовать библиотеки классов и шаблонов вместо привычных C-ных конструкций. Тот же STL, например. Берем std::vector<int> и у нас нет проблем с приведенными примерами вообще.
Помню, что когда прочитал 3-е издание Страуструпа, то понял, что C++ стал совсем другим языком. Который уже нужно использовать совсем не так, как "C с классами".
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, AVC, Вы писали:
CX>>Может, перейдем на ты? Удобнее, да и форуму соответствует.
AVC>С удовольствием. AVC>Да и то правда — какое там "Вы", когда Ариан-5 все-таки упал!
Точно!
AVC>Стыжусь, но я действительно этого не знал! AVC>Comeau C++ online не потребовался — уже второй домашний компилятор Си++ (GNU C++) с этим справился. AVC>К сожалению, код AVC>
AVC> p = new int[10];
AVC> foo(p); // передаем указатель (или все-таки массив? :) )
AVC>
AVC>так и не скомпилировался. А ведь вроде бы — чем не массив? AVC>У меня по ходу дела два вопроса. AVC>1) Почему здесь все знатоки Си++ ссылаются, как правило, на Comeau C++? AVC>(Помню, этим меня удивил еще Павел Кузнецов.) AVC>Comeau C++ особенно продвинут? Или здесь важнее его доступность online?
По этому поводу тебе уже Кодт ответил, но вставлю свои пять копеек и я. Дело в том, что Comeau C++ на сегодняшний день, пожалуй, самый лучший компилятор C++ в части соответствия стандарту. А также намного более интеллектуальный, чем другие. Например, на твой код (попытку обращения к 1023-му элементу 10-елементного массива) он выдает warning о возможности out of bound.
"ComeauTest.c", line 9: warning: subscript out of range
printf("%d\n", p[1023]); // например, так; ах, я кажется вышел за границу массива... но откуда мне было знать?
AVC>2) Не растет ли в данном случае размер кода, если foo вызывается с массивами разной размерности?
Да, для массива каждой размерности создается своя функция. Это общее свойство темплейтов. Если хочется этого избежать, надо использовать стандартные классы (vector и т.д.), как уже советовал Евгений (eao197). Да и вообще, использование голых массивов, как и голых указателей не должно быть повсеместным. Надо просто использовать стандартную библиотеку, которая, кстати, является частью языка, т.к. зафиксирована в стандарте.
Вообще, сегодняшний C++ — это совсем другой язык (не тот, что был 10 лет назад). Эти изменения, на первый взгляд, не так заметны, но как только начинаешь углубляться, они все более и более проявляются. У меня складывается такое впечатление (поправь меня, если я неправ), что ты, говоря о C++, говоришь не о современном языке, а о "C с классами". На самом деле я очень много людей встречал в своем близком окружении, которые не видят этой разницы. Да что там говорить, каких-нибудь три года назад я и сам был таким же.
В общем, у меня предложение. Ты говорил об идее, вложенной в Оберон, которую, как тебе казалось, не видят на этих форумах. Мы вроде сошлись на мнении, что идея видна и понятна, не так ли? Попытайся теперь понять идею, которая вложена в современный C++. Я потихоньку начал изучать Оберон (для общего развития), — почему бы тебе не взяться за изучение современного C++? А через некоторое время мы опять вернемся к этой теме и посмотрим, насколько изменились наши взгляды. Что скажешь?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[9]: Что толку в Ада если Ариан 5 все равно упал
Алексей, давай я твои примеры сейчас переделаю немного, ок?
AVC>А есть способ создать указатель на массив в динамической памяти, не прибегая к явному приведению типа? AVC>
AVC>int (*p)[10] = ((*)[10]) new int[10]; // радует также возможность употребить одну и ту же константу трижды :)
AVC>
Например, так:
vector<int> *p = new vector<int>(10);
// Конечно же, удалить тоже надо не забыть. А лучше всего воспользоваться смарт-пойнтером. Например, так:
auto_ptr<vector<int> > p(new vector<int>(10));
// Вот тут даже удалять не надо. Но остается проблема с семантикой передачи владения у auto_ptr.
// Хорошо, сделаем так:
boost::shared_ptr<vector<int> > p(new vector<int>(10));
// Тут уже можно копировать сколько угодно и куда хочешь. Но как же быть, если хочется избежать оверхеда
// от дополнительного выделения памяти для счетчика? Например, используя linked_ptr от Максима Егорушкина
// или другие, обеспечивающие иное поведение. В общем, на выбор пожаловаться нельзя.
AVC>Посмотрим, решает ли все проблемы введение указателя на массив.
[skipped]
А теперь так:
template <typename Array>
void foo(Array &p)
{
}
void test_foo(size_t size)
{
vector<int> a(10);
auto_ptr<vector<int> > p(new vector<int>(size));
foo(a); // Все работает
foo(*p); // И здесь тоже!
}
AVC>Ай, получил сообщение компилятора (GNU C++): AVC>
AVC>Internal compiler error 243.
AVC>К чему бы это? Наверное, к дождю. Уже голова болит от того, что даже такая мелочь здесь проблема. AVC>Может, какому-нибудь компилятору Си++ (например, Comeau C++) повезло бы здесь больше? Но выяснить это уже нет сил.
Интересно, а какая версия GCC? Небось старичка используешь? Потому как у меня GCC 3.4.2 отругался на этот код как положено. Ты используешь run-time value в объявлении указателя на массив. Нельзя. Должна быть compile-time. Посмотри мой код — там эти проблемы решены, причем без всяких усилий с моей стороны — я просто использовал стандартную библиотеку.
К>>Один из наиболее соответвтвующих Стандарту компиляторов. (Хотя тоже есть бажки, но, в отличие от MS, он не занимается обратной совместимостью с хреновыми предшественниками). К>>Ну и онлайновость — приятный бонус.
AVC>Спасибо за информацию! AVC>А что касается "совместимости с хреновыми предшественниками", то разве только MS этим занимается? AVC>Да весь Си++ на этом выстроен, как Петербург на болоте!
Ты путаешь две вещи:
1. Совместимость с C кодом (практически все компиляторы стараются этому соответствовать)
2. Совместимость с хреновыми предшественниками (более ранними и более плохими версиями компиляторов)
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[9]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, AVC, Вы писали:
AVC>А что касается "совместимости с хреновыми предшественниками", то разве только MS этим занимается? AVC>Да весь Си++ на этом выстроен, как Петербург на болоте!
Как петербуржец и сиплюсплюсник, я должен обидеться или возгордиться?
Насчёт чудесатости: необходимо и достаточно, чтобы
1) некто единожды написал библиотеку строгих типов с требуемой функциональностью
2) остальные пользовались именно ею, а не мешали в кучу с голыми сишными типами
STL + boost, большей частью, уже выполнили п.1. Осталось дело за малым — за п.2...
А тут уже дело привычки: если кому-то проще накопипастить
Здравствуйте, CrystaX, Вы писали:
CX>Вообще, сегодняшний C++ — это совсем другой язык (не тот, что был 10 лет назад). Эти изменения, на первый взгляд, не так заметны, но как только начинаешь углубляться, они все более и более проявляются. У меня складывается такое впечатление (поправь меня, если я неправ), что ты, говоря о C++, говоришь не о современном языке, а о "C с классами". На самом деле я очень много людей встречал в своем близком окружении, которые не видят этой разницы. Да что там говорить, каких-нибудь три года назад я и сам был таким же.
В принципе, ты прав.
В основном, и я, и большинство ребят, пишущих у нас на Си++, используют его как "Си с классами".
Не совсем, конечно. Библиотекой стандартных шаблонов все-таки иногда пользуемся. (Но и от нее я не в восторге.)
Думаю, что вы с Евгением действительно нашли источник многих наших недоразумений.
Вероятно, "народный" (практикуемый не только "гуру") Си++ стал бурно меняться после принятия стандарта языка, когда я уже не так внимательно следил за его развитием.
Тому есть свои причины. У нас много сугубо прикладной работы, некоторые ребята — даже не профессиональные программисты, а просто пишущие на Си++ специалисты. Польза от новшеств языка для нас не слишком велика, а "накладные расходы" — напротив.
Еще мне кажется, что Си++ — уже не только (а по вашим примерам — и не столько ) язык процедурного и объектно-ориентированного программирования. Возможно, в него "затесались" элементы плохо знакомой мне парадигмы, например — функционального программирования.
Я охотно допускаю мысль, что новые черты языка делают его мощным орудием писателей библиотек.
Но, увы, пока не вижу реальной пользы для наших программистов. А вот головокружение от некоторых публикуемых вами трюков — действительно чувствую.
CX>В общем, у меня предложение. Ты говорил об идее, вложенной в Оберон, которую, как тебе казалось, не видят на этих форумах. Мы вроде сошлись на мнении, что идея видна и понятна, не так ли? Попытайся теперь понять идею, которая вложена в современный C++. Я потихоньку начал изучать Оберон (для общего развития), — почему бы тебе не взяться за изучение современного C++? А через некоторое время мы опять вернемся к этой теме и посмотрим, насколько изменились наши взгляды. Что скажешь?
Я думаю, это хорошая мысль.
Так честно. Хотя, боюсь. усилия, которые нам придется приложить, вряд ли будут равными.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[9]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, AVC, Вы писали:
AVC>В принципе, ты прав. AVC>В основном, и я, и большинство ребят, пишущих у нас на Си++, используют его как "Си с классами". AVC>Не совсем, конечно. Библиотекой стандартных шаблонов все-таки иногда пользуемся. (Но и от нее я не в восторге.) AVC>Думаю, что вы с Евгением действительно нашли источник многих наших недоразумений. AVC>Вероятно, "народный" (практикуемый не только "гуру") Си++ стал бурно меняться после принятия стандарта языка, когда я уже не так внимательно следил за его развитием. AVC>Тому есть свои причины. У нас много сугубо прикладной работы, некоторые ребята — даже не профессиональные программисты, а просто пишущие на Си++ специалисты. Польза от новшеств языка для нас не слишком велика, а "накладные расходы" — напротив. AVC>Еще мне кажется, что Си++ — уже не только (а по вашим примерам — и не столько ) язык процедурного и объектно-ориентированного программирования. Возможно, в него "затесались" элементы плохо знакомой мне парадигмы, например — функционального программирования.
Да, так и есть. Особенно если говорить о метапрограммировании на шаблонах.
AVC>Я охотно допускаю мысль, что новые черты языка делают его мощным орудием писателей библиотек. AVC>Но, увы, пока не вижу реальной пользы для наших программистов. А вот головокружение от некоторых публикуемых вами трюков — действительно чувствую.
Реальная польза C++ (в современном его понимании) не видна сразу. Я тоже так думал довольно большое время. Но все же стоит попытаться ее увидеть.
CX>>В общем, у меня предложение. Ты говорил об идее, вложенной в Оберон, которую, как тебе казалось, не видят на этих форумах. Мы вроде сошлись на мнении, что идея видна и понятна, не так ли? Попытайся теперь понять идею, которая вложена в современный C++. Я потихоньку начал изучать Оберон (для общего развития), — почему бы тебе не взяться за изучение современного C++? А через некоторое время мы опять вернемся к этой теме и посмотрим, насколько изменились наши взгляды. Что скажешь?
AVC>Я думаю, это хорошая мысль. AVC>Так честно. Хотя, боюсь. усилия, которые нам придется приложить, вряд ли будут равными.
В этом нет никаких сомнений — современный C++ выучить очень сложно. Но дело ведь в том, что его и не надо полностью изучать для того, чтоб увидеть новые стороны. К тому же, нас никто не торопит.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[10]: Что толку в Ада если Ариан 5 все равно упал
Здравствуйте, eao197, Вы писали:
AVC>>К чему бы это? Наверное, к дождю. Уже голова болит от того, что даже такая мелочь здесь проблема. AVC>>Как говорила девочка из одной книжки: "Все чудесатее и чудесатее!"
E>Алексей, помнишь: "Это не дурдом, это особенность"
E>Просто для того, чтобы не забивать себе голову такими проблемами, нужно использовать библиотеки классов и шаблонов вместо привычных C-ных конструкций. Тот же STL, например. Берем std::vector<int> и у нас нет проблем с приведенными примерами вообще.
E>Помню, что когда прочитал 3-е издание Страуструпа, то понял, что C++ стал совсем другим языком. Который уже нужно использовать совсем не так, как "C с классами".
Евгений, в этом пункте я согласен с тобой и с Дмитрием.
Действительно, Си++ сильно изменился.
Возможно, я просто отстал от его развития, как отстают от поезда. Вышел купить арбуз — и только ту-ту...
Тут вы оба правы.
Но я по прежнему считаю, что Си++ стал слишком сложным, что он сам во многом стал проблемой.
Понимаешь, я привык смотреть на предмет и сквозь язык. ИМХО, язык должен быть прозрачным и незаметным.
Именно так обстоит дело с Обероном.
Почти так было даже с Си++ как "Си с классами", которым я достаточно успешно пользуюсь уже много лет.
А сейчас — не так.
Я уверен, что большинство Си++программистов не умеет должным образом пользоваться новым Си++.
(Например, я не умею. Хотя, с некоторым усилием, все-таки понимаю ваши (твои, Дмитрия, Кодта) примеры. Но по прежнему есть чувство, что эта сложность неоправданная, чрезмерная.)
Библиотеки по прежнему пишут "гуру".
Что-то здесь не так...
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.