Arioch2 wrote: > AJD>>AFAIK в то время у сишных компилеров тоже не было оптимизаторов. А > компилер очень быстрый > А опимизирующий линкер, выкидывающий из библиотек (не исходников, а > скажем так .LIB+OBJ) весь неиспользуемый код — когда в C++ появился ?
Где-то в районе 84 года. Для С появился еще в 70-х.
> A>А ты хочешь сказать, что в Паскале можно свободно писать A := B + 2, > где A и B — указатели? > А зачем? динамические массивы ?
Не только. В частности, указатели являются частным случаем итераторов,
которые используются в обобщенных алгоритмах.
> A>Да? Чтобы объявить указатель на указатель, сколько кода написать нужно? > Кода ? > var pp: ^Pointer; > Сколько тут кода ?
К указателям обращаться не так удобно.
> A> А как тебе работа с > A>динамическим массивом? > В чистом виде, с SetLength(), Length() и т.д. не было до довольно > поздних Delphi. > Через type dynarr=array[0..0] of xxx, а потом класть это на heap — по > крайней мере в TP5.5
Ага, я помню. Объявлялся массив в 65536 элементов, а потом создавался в
куче (обычно много меньшего размера). Замечательная понятность...
> Обойти можно. Вот обойти чрезмерное приведение в компиляторе C — труднее > type str = array [0..100] of char; data: array [0..100] of byte; > var x: str; y: data absolute x; // На ДВК/УКНЦ/БК даже красивее — var y origin x: data;
А зачем такое? В С++ это считается хаком — а в Паскале обходом типизации.
Но если уж очень надо...
union
{
char str[100];
byte data[100];
};
Ничуть не менее понятно...
> AJD>>есть и обьединения и перечисления и даже множества > A>Открой глаза незнающему, пожалуйста. Как в паскале объявить объединение? > type union = record Name: string (* и ещё что-нибудь *) case byte of 0: (asInt: integer); 1: (asPtr: pointer); end;
Это discriminated union, а не объединение в понятии С. В С++, кстати,
есть гораздо более мощный boost::variant.
А вообще, в Pascal'е нет темплейтов и обобщенного программирования. Нет
умных указателей (при ручном управлениии памятью!), нет множественного
наследования (а хотелось бы), нет перегрузки операторов (вспомню как
писал 3D-графику с кватернионами и матрицами — в дрожь бросает).
C>Где-то в районе 84 года. Для С появился еще в 70-х.
Тут писали "Для меня "то время" — это время, когда я писал под ДОС (1995-1998). "
Было это под DOS ?
C>Не только. В частности, указатели являются частным случаем итераторов,
итераторы — это где надо +1 / -1 ?
Pred & Succ
C>К указателям обращаться не так удобно.
???
C>Ага, я помню. Объявлялся массив в 65536 элементов,
в 1 элемент.
С чем сравнить ? объявился указатель и стал массивом ? Дело вкуса.
Кстати еще размер массива в 64кб max, действительно. Но тут меньше паскаль и больше ограничения 16 бит x86.
>> Обойти можно. Вот обойти чрезмерное приведение в компиляторе C — труднее >> type str = array [0..100] of char; data: array [0..100] of byte; >> var x: str; y: data absolute x; // На ДВК/УКНЦ/БК даже красивее — var y origin x: data; C>А зачем такое? В С++ это считается хаком — а в Паскале обходом типизации.
Да вот приведение char к byte/shortint человеку надо, а Ord(x) писать надоело.
Это только к тому и относилось. Массовое приведение char к int я хаком и считаю.
C>Ничуть не менее понятно...
Ты кажется сбился с фазы
Это не я доказываю, что Паскаль всех нагнет. Это человеку я отвечаю, как не только в С, но и в Паскале можно то, то и это
>> AJD>>есть и обьединения и перечисления и даже множества >> A>Открой глаза незнающему, пожалуйста. Как в паскале объявить объединение? >> type union = record Name: string (* и ещё что-нибудь *) case byte of 0: (asInt: integer); 1: (asPtr: pointer); end; C>Это discriminated union, а не объединение в понятии С.
в чём разница ?
C> В С++, кстати, C>есть гораздо более мощный boost::variant.
Сравни год появление boost и, скажем Turbo Pascal 4.0
C>А вообще, в Pascal'е нет темплейтов и обобщенного программирования.
Увы. Но, наверное, с выходом .Net 2 будет.
C>умных указателей (при ручном управлениии памятью!),
Есть интерфейсы. умных указателей на отдельный integer и правда нет, но нужны ли ?
C> нет множественного наследования (а хотелось бы),
"nj уже не сюда, а в соседнюю ветку, C++ мы С++ :D
C>нет перегрузки операторов (вспомню как C>писал 3D-графику с кватернионами и матрицами — в дрожь бросает).
Нету. Но как-то это напоминает войну с begin и end
Arioch2 wrote: > C>Где-то в районе 84 года. Для С появился еще в 70-х. > Тут писали "Для меня "то время" — это время, когда я писал под ДОС > (1995-1998). " > Было это под DOS ?
Было. Насчет Borland C++ не уверен, но в Watcom точно было (я как раз в
то время в нем писал). В DJGPP тоже было с момента создания.
> C>Не только. В частности, указатели являются частным случаем итераторов, > итераторы — это где надо +1 / -1 ?
Не только, еще бывает нужна арифметика итераторов и изменение на заданую
величину.
> C>К указателям обращаться не так удобно. > ???
Арифметика очень неудобна.
> C>Ага, я помню. Объявлялся массив в 65536 элементов, > в 1 элемент.
Нет, именно в 65536, иначе Паскаль жаловался на переполнение массива.
Хотя сейчас уже точно и не вспомню.
> С чем сравнить ? объявился указатель и стал массивом ? Дело вкуса.
Указатель в С++ массивом не становится — это разные вещи, просто доступ
к массиву идет через указатель(в С есть тождество: A[i]==*(A+i)==i[A]).
> C>А зачем такое? В С++ это считается хаком — а в Паскале обходом типизации. > Да вот приведение char к byte/shortint человеку надо, а Ord(x) писать > надоело.
Так char ведь _это_ _и_ _есть_ байт (в большинстве случаев). С ним
возможна нормальная арифметика с обычными правилами integer
promotion'ов. Почему в Паскале тип 'char' считается особым — мне
непонятно, так как это преимуществ никаких не дает.
> Это только к тому и относилось. Массовое приведение char к int я хаком и > считаю.
Почему?
>> > type union = record Name: string (* и ещё что-нибудь *) case byte of > 0: (asInt: integer); 1: (asPtr: pointer); end; > C>Это discriminated union, а не объединение в понятии С. > в чём разница ?
В слове "discriminated" — то есть в структуре в виде скрытого поля
записывается "дискриминатор", показывающий какой тип активен. В union'ах
дискриминатора нет. Стандартный пример:
union IPAddress
{
long long quad;
long word[2];
long byte[4];
};
IPAddress adr;
adr.byte[0]=1; adr.byte[1]=2; ...
write(sock,&adr.quad,sizeof(long long));
> C> В С++, кстати, > C>есть гораздо более мощный boost::variant. > Сравни год появление boost и, скажем Turbo Pascal 4.0
И что? В Delphi оно до сих пор удобнее не стало.
> C>умных указателей (при ручном управлениии памятью!), > Есть интерфейсы. умных указателей на отдельный integer и правда нет, но > нужны ли ?
Интерфейсы в TP4? Либо говорим о современном Паскале (aka Delphi), либо
о древних версиях.
> C>нет перегрузки операторов (вспомню как > C>писал 3D-графику с кватернионами и матрицами — в дрожь бросает). > Нету. Но как-то это напоминает войну с *begin* и *end*
Перегрузка _реально_ упрощает программы со сложными вычислениями с
нестандартными объектами.
Здравствуйте, Arioch2, Вы писали:
GZ>>Еще не надо забывать, что это время жизни объекта. Что есть вери гуд. И чего нет в пасквиле. A>Угу, в нём гораздо лучше:
Сравним?
Здравствуйте, Cyberax, Вы писали:
>> C>Не только. В частности, указатели являются частным случаем итераторов, >> итераторы — это где надо +1 / -1 ? C>Не только, еще бывает нужна арифметика итераторов и изменение на заданую C>величину.
Все же реже
>> C>К указателям обращаться не так удобно. >> ??? C>Арифметика очень неудобна.
Это уже повтор.
>> C>Ага, я помню. Объявлялся массив в 65536 элементов, >> в 1 элемент. C>Нет, именно в 65536, иначе Паскаль жаловался на переполнение массива. C>Хотя сейчас уже точно и не вспомню.
Проверка границ массивов может включаться и отключаться, если ты про это.
Или ты про ограничение сверху? Оно было на размер массива, чтобы он целиком убирался в 64Кб.
Убрано в 32-битный компиляторах типа VirtualPascal.
>> С чем сравнить ? объявился указатель и стал массивом ? Дело вкуса. C>Указатель в С++ массивом не становится — это разные вещи, просто доступ
А это уже, применительно к чтению исxодников, и етсь привычка. C>к массиву идет через указатель(в С есть тождество: A[i]==*(A+i)==i[A]).
Особенно это тождество смотрится, если A — структура.
>> C>А зачем такое? В С++ это считается хаком — а в Паскале обходом типизации. >> Да вот приведение char к byte/shortint человеку надо, а Ord(x) писать >> надоело. C>Так char ведь _это_ _и_ _есть_ байт (в большинстве случаев).
Не в Паскале, там это разные типы.
C>promotion'ов. Почему в Паскале тип 'char' считается особым — мне C>непонятно, так как это преимуществ никаких не дает.
Да ну? В C конечно не дает. Насчет C++ сходу не скажу, но думаю там будут свои заморочки.
А вот возможность сложить 5 обычных char и 10 юникодных и без всяких путаниц получить строчку из 15 символов — даёт. И отсутствие путаницы — именно потому что char — не число.
А вот чем мешает Ord() — вопрос.
И то и другое по большому счету синтаксический сахар маловажный, но мне больше приятен паскалевский.
>> Это только к тому и относилось. Массовое приведение char к int я хаком и >> считаю. C>Почему?
Массовое не в смысле объема данных, а в смысле объема кода.
Если мне нужно зашифровать/заархивировать буфер, или колдировку сменить и т.д. — то преобразование типов выполняется один раз, хоть в цикле по букве, хоть сразу над буфером.
>>> > type union = record Name: string (* и ещё что-нибудь *) case byte of >> 0: (asInt: integer); 1: (asPtr: pointer); end; >> C>Это discriminated union, а не объединение в понятии С. >> в чём разница ? C>В слове "discriminated" — то есть в структуре в виде скрытого поля C>записывается "дискриминатор", показывающий какой тип активен.
Так и думал.
Чистый Pascal мёртв и никогда не жил.
В Turbo такого не было никогда.
Перечитай мой пример, пожалуйста. Я там после case не просто так поставил не имя переменной-члена, а тип.
>> C> В С++, кстати, >> C>есть гораздо более мощный boost::variant. >> Сравни год появление boost и, скажем Turbo Pascal 4.0 C>И что? В Delphi оно до сих пор удобнее не стало.
дженериков в Delphi нет. Уже говорили.
Но отвечал я на вопрос человека, заговорившего про конкретный промежуток времени и конкретную OS
C>Интерфейсы в TP4? Либо говорим о современном Паскале (aka Delphi), либо C>о древних версиях.
Вот-вот. Так шаг за шагом начинаем говорить ни о чём. Я отвечал ... не хочу повторяться
C>Перегрузка _реально_ упрощает программы со сложными вычислениями с C>нестандартными объектами.
И все же это синтаксический сахар. Тук кто-то советовал препроцессорами пользоваться пасквилятникам.
Могу этот совет вернуть сишникам
Ну и отослать к аналогичному сахару насчет char + char +widechar + char = widestring
WH> File file4("file4"); WH> File file5("file5"); WH>Повтори на паскале...
/me думает
TCollection, которая объектами управляет ?
Или через интерфейсы...
Надо еще глянуть в сторону финализации динамических массивов, может быть там что-то было.
(шепотом... а вот потом где-то затрётся file9 NULL'ом по ошибке — какой феерверк будет)
Не всё что по-другому — сразу хуже.
И это только за одну минуту в голову пришло
WH>ЗЫ А за with надо на месте руки отрывать.
За char который непонятно число или буква — тоже.
Arioch2 wrote: >> > C>Не только. В частности, указатели являются частным случаем итераторов, >> > итераторы — это где надо +1 / -1 ? > C>Не только, еще бывает нужна арифметика итераторов и изменение на заданую > C>величину. > Все же реже
Но бывает нужна. Для Delphi есть некое подобие STL, но намного менее
красивое.
>> > C>Ага, я помню. Объявлялся массив в 65536 элементов, >> > в 1 элемент. > C>Нет, именно в 65536, иначе Паскаль жаловался на переполнение массива. > C>Хотя сейчас уже точно и не вспомню. > Проверка границ массивов может включаться и отключаться, если ты про это.
Да, но иногда хотелось иметь ее включенной.
> C>Указатель в С++ массивом не становится — это разные вещи, просто доступ > А это уже, применительно к чтению исxодников, и етсь привычка. > C>к массиву идет через указатель(в С есть тождество: A[i]==*(A+i)==i[A]). > Особенно это тождество смотрится, если A — структура.
А какие проблемы? Странно выглядит только самая правая часть тождества,
но про нее вообще многие не знают.
>> > Да вот приведение char к byte/shortint человеку надо, а Ord(x) писать >> > надоело. > C>Так char ведь _это_ _и_ _есть_ байт (в большинстве случаев). > Не в Паскале, там это разные типы.
А зачем? Это не добавляет абстракции, а только лишней головной боли.
> C>promotion'ов. Почему в Паскале тип 'char' считается особым — мне > C>непонятно, так как это преимуществ никаких не дает. > Да ну? В C конечно не дает. Насчет C++ сходу не скажу, но думаю там > будут свои заморочки.
С типом char? Не припомню, за исключением его знаковости.
> А вот возможность сложить 5 обычных char и 10 юникодных и без всяких > путаниц получить строчку из 15 символов — даёт. И отсутствие путаницы — > именно потому что char — не число.
Во-первых, _каких_ юникодных char'ов? Их много, если вы не знали: есть
UCS2 BE/LE, есть суррогаты, есть UCS4. А есть еще широкие не-Unicode
кодировки.
Кстати, в C++/C тоже есть широкие символы, имеющие тип wchar_t. Никакой
путаницы с ними нет:
> А вот чем мешает Ord() — вопрос.
Лишний мусор там, где он совсем не нужен. Я не ворзражаю против
дополнительной абстракции для символов, но только если она будет оправдана.
На самом деле, это весьма непростая задача (из-за огромной путаницы с
Unicode'ом). Есть целые библиотеки для ее решения (ICU от IBM, например).
> Массовое не в смысле объема данных, а в смысле объема кода. > Если мне нужно зашифровать/заархивировать буфер, или колдировку сменить > и т.д. — то преобразование типов выполняется один раз, хоть в цикле по > букве, хоть сразу над буфером.
Нет смысла выделять char в отдельный тип — без контекста (кодировки,
языка и т.п.) с ним все равно ничего осмысленного кроме простой
арифметики или сравнений выполнить нельзя. А для арифметики и сравнений
вполне подойдет обычный интегральный тип.
> C>В слове "discriminated" — то есть в структуре в виде скрытого поля > C>записывается "дискриминатор", показывающий какой тип активен. > Так и думал. > Чистый Pascal мёртв и никогда не жил. > В Turbo такого не было никогда.
Именно то что я описал и было в TP. Дискриминатор записывался перед
вариантной переменной и занимал 1 байт, если не ошибаюсь.
> Перечитай мой пример, пожалуйста. Я там после case не просто так > поставил не имя переменной-члена, а тип.
Да, а теперь перечитайте то что я написал:
скрытого поля записывается "дискриминатор", показывающий какой тип активен.
> И все же это синтаксический сахар. Тук кто-то советовал препроцессорами > пользоваться пасквилятникам. > Могу этот совет вернуть сишникам > Ну и отослать к аналогичному сахару насчет char + char +widechar + char > = widestring
А зачем это надо? В С++ это вообще не скомпилируется — из-за
несовпадений типов (char к wchar_t не приводится без явного каста).
Здравствуйте, Cyberax, Вы писали:
C>Но бывает нужна. Для Delphi есть некое подобие STL, но намного менее C>красивое.
Даже то ли три то ли четыре. Но все они, конечно, обход ограничений, и поэтому сами ограниченные.
Но, видимо, кому-то нужны были
>> C>Нет, именно в 65536, иначе Паскаль жаловался на переполнение массива. >> C>Хотя сейчас уже точно и не вспомню. >> Проверка границ массивов может включаться и отключаться, если ты про это. C>Да, но иногда хотелось иметь ее включенной.
Включай и выключай.
М.б. тогда в Watcom'е и были проверки длины *динамических* массивов, не знаю.
Но Watcom и стоил сколько и работал долго
>> C>Указатель в С++ массивом не становится — это разные вещи, просто доступ >> А это уже, применительно к чтению исxодников, и етсь привычка. >> C>к массиву идет через указатель(в С есть тождество: A[i]==*(A+i)==i[A]). >> Особенно это тождество смотрится, если A — структура. C>А какие проблемы? Странно выглядит только самая правая часть тождества, C>но про нее вообще многие не знают.
Но если ты это привел как тождество — то и правая должна иметь смысл.
>>> > Да вот приведение char к byte/shortint человеку надо, а Ord(x) писать >>> > надоело. >> C>Так char ведь _это_ _и_ _есть_ байт (в большинстве случаев). >> Не в Паскале, там это разные типы. C>А зачем? Это не добавляет абстракции, а только лишней головной боли
Это добавляет абстракции и убирает головную боль там где строки мешаются с числами.
>> будут свои заморочки. C>С типом char? Не припомню, за исключением его знаковости.
char a='a', b='b';
puts (a+b);
Должно вывести на экран (на уровне простой человеческой логики) строку "ab"
Вот если отказаться от человеческой логики в пользу string.h — тогда конечно, никаких заморочек
>> А вот возможность сложить 5 обычных char и 10 юникодных и без всяких >> путаниц получить строчку из 15 символов — даёт. И отсутствие путаницы — >> именно потому что char — не число. C>Во-первых, _каких_ юникодных char'ов?
Тех, которые есть в языке.
Кажется через макрос TCODE они в C++ делаются ?
C>Кстати, в C++/C тоже есть широкие символы, имеющие тип wchar_t. Никакой C>путаницы с ними нет: C>
C>char c='A';
C>char wc=L'A';
C>
puts (c + wc); ???
>> А вот чем мешает Ord() — вопрос. C>Лишний мусор там, где он совсем не нужен.
А я вот так считаю про лишний мусор там где нужно просто соединить два-три символа в одну строку.
C>На самом деле, это весьма непростая задача (из-за огромной путаницы с C>Unicode'ом). Есть целые библиотеки для ее решения (ICU от IBM, например).
ICU так и не собрался посмотреть, с другой тсороны он изначально илёт от Явы, насколько помню. Не знаю, насколько он естественнен на C++.
C>Нет смысла выделять char в отдельный тип — без контекста (кодировки, C>языка и т.п.)
А программа вероятно вне контекста работает? Такой вот сфероконь в вакууме ? C> с ним все равно ничего осмысленного кроме простой C>арифметики или сравнений выполнить нельзя.
Как минимум — соединения.
Можно бы было еще умножение на число определить, типа дупликации символов/строк
Впрочем это уже Питоном попахивает
C>А для арифметики
Угу, арифметика над буквами, я правильно понимаю? Символьная арифметика, прям в текстовом представлении чисел ?
Как там говорил Каганов (по памяти): Целочисленная ошибка: попытка деления на букву "о".
>> Перечитай мой пример, пожалуйста. Я там после case не просто так >> поставил не имя переменной-члена, а тип. C>Да, а теперь перечитайте то что я написал: C>
C>скрытого поля записывается "дискриминатор", показывающий какой
C>тип активен.
Не знаю, надо бы проверить.
Никогда не видел его на уровне языка.
Если он там и еcть, то на правах атавизма ни на что не влияющего.
C>несовпадений типов (char к wchar_t не приводится без явного каста).
И эти люди считают проблемой Ord !
Здравствуйте, Arioch2, Вы писали:
A>Здравствуйте, Cyberax, Вы писали:
>>> будут свои заморочки. C>>С типом char? Не припомню, за исключением его знаковости.
A>char a='a', b='b'; A>puts (a+b);
A>Должно вывести на экран (на уровне простой человеческой логики) строку "ab"
Тут уже проходила тема, что конкатенация — это не сложение и использование плюса не есть корректно. По меньшей мере она не коммуникативная операция. Хотя это в сторону.
Смысл сишного варианта в том, что там нет операции конкатенации как таковой и это надо понимать (и вообще по сути нет операций над массивами, которыми являются строки, как таковыми). Ну нет в си строкового типа!
Arioch2 wrote: >> > C>Нет, именно в 65536, иначе Паскаль жаловался на переполнение массива. >> > C>Хотя сейчас уже точно и не вспомню. >> > Проверка границ массивов может включаться и отключаться, если ты про это. > C>Да, но иногда хотелось иметь ее включенной. > Включай и выключай.
Угу, очень удобно.
> М.б. тогда в Watcom'е и были проверки длины *динамических* массивов, не > знаю. Но Watcom и стоил сколько и работал долго
std::vector — там он был.
> C>А какие проблемы? Странно выглядит только самая правая часть тождества, > C>но про нее вообще многие не знают. > Но если ты это привел как тождество — то и правая должна иметь смысл.
Ну так она имеет смысл — если обратить внимание на центр тождества. В С
запись A[i] значит *(A+i), а так как сложение коммутативно, то
*(A+i)==*(i+A)==i[A].
> C>А зачем? Это не добавляет абстракции, а только лишней головной боли > Это добавляет абстракции и убирает головную боль там где строки мешаются > с числами.
Не помню таких проблем, кроме как с printf'ом.
>> > будут свои заморочки. > C>С типом char? Не припомню, за исключением его знаковости. > char a='a', b='b'; > puts (a+b); > Должно вывести на экран (на уровне простой человеческой логики) строку "ab"
Почему? Мы складываем числа, например puts('1'+1) на уровне простой
логики должно вывести '2'.
> C>Во-первых, _каких_ юникодных char'ов? > Тех, которые есть в языке.
В С++ в языке есть wchar_t, для которого ничего не гарантировано (и это
минус), можно явно использовать wchar_t как хранилище для UCS2 или
использовать свой тип для UCS4.
> C>char c='A'; > C>char wc=L'A'; > puts (c + wc); ???
Нефиг складывать символы. Кстати! Для Delphi оно тоже небезопасно:
SomeWinFunc(@'a',@'b');
Этот код молчаливо упадет, если функция будет ожидать строку, а не символ.
>> > А вот чем мешает Ord() — вопрос. > C>Лишний мусор там, где он совсем не нужен. > А я вот так считаю про лишний мусор там где нужно просто соединить > два-три символа в одну строку.
А они в какой кодировке? А с суррогатами оно работает? Что будет, если я
сложу русский 'а' и символ в финской кодировке?
> C>На самом деле, это весьма непростая задача (из-за огромной путаницы с > C>Unicode'ом). Есть целые библиотеки для ее решения (ICU от IBM, например). > ICU так и не собрался посмотреть, с другой тсороны он изначально илёт от > Явы, насколько помню. Не знаю, насколько он естественнен на C++.
Нормально, там все достаточно низкого уровня.
> C>Нет смысла выделять char в отдельный тип — без контекста (кодировки, > C>языка и т.п.) > А программа вероятно вне контекста работает? Такой вот сфероконь в вакууме ?
Нет, просто для корректного выполнения даже "простых" операций типа
сложения строк нужно знать достаточно много параметров. И простой "a+b"
прокатывает только в самых простых случаях.
В С++ поступили честно — строки рассматриваются просто как набор байт и
никак не интерпретируются контейнерами. Для работы с локалями есть
специальный набор функций (facet'ы в потоках и т.п.).
В Паскале наоборот, выбрали некое поведение и объявили его "The Only
Right Way".
> C> с ним все равно ничего осмысленного кроме простой > C>арифметики или сравнений выполнить нельзя. > Как минимум — соединения.
Нет, так как они тоже зависят от кодировок. Имеет смысл только бинарная
конкатенация, для которой вполне достаточно арифметического представления.
> Можно бы было еще умножение на число определить, типа дупликации > символов/строк
Тоже прекрасно работают с бинарными данными.
> C>А для арифметики > Угу, арифметика над буквами, я правильно понимаю? Символьная арифметика, > прям в текстовом представлении чисел ?
Да, для hash-контейнеров, например.
> Как там говорил Каганов (по памяти): Целочисленная ошибка: попытка > деления на букву "о".
Без проблем.
> C>Да, а теперь перечитайте то что я написал: > C>скрытого поля записывается "дискриминатор", показывающий какой > C>*тип* активен. > Не знаю, надо бы проверить. > Никогда не видел его на уровне языка. > Если он там и еcть, то на правах атавизма ни на что не влияющего.
Именно на уровне языка.
> C>несовпадений типов (char к wchar_t не приводится без явного каста). > И эти люди считают проблемой Ord !
А какое должно быть правильное поведение? Можно узнать?
>> C>Да, но иногда хотелось иметь ее включенной. >> Включай и выключай. C>Угу, очень удобно.
В те вермена ее включали в основном для отладки. Не те процессоры были
>> М.б. тогда в Watcom'е и были проверки длины *динамических* массивов, не >> знаю. Но Watcom и стоил сколько и работал долго C>std::vector — там он был.
А елси я в нем хотел отключить проверку ?
>> C>А какие проблемы? Странно выглядит только самая правая часть тождества, >> C>но про нее вообще многие не знают. >> Но если ты это привел как тождество — то и правая должна иметь смысл. C>Ну так она имеет смысл — если обратить внимание на центр тождества. В С C>запись A[i] значит *(A+i), а так как сложение коммутативно, то C>*(A+i)==*(i+A)==i[A].
Нет-нет, давай без алгебры, на пальцах.
Какой смысл все же имеет i[A], где A — например, структура.
Раз уж это — преимущество C — то смысл должен быть. Иначе это тождество получается интересной гимнастикой для умая у которой иногда случайно бывает практическое применение.
>>> > будут свои заморочки. >> C>С типом char? Не припомню, за исключением его знаковости. >> char a='a', b='b'; >> puts (a+b); >> Должно вывести на экран (на уровне простой человеческой логики) строку "ab" C>Почему? Мы складываем числа, например puts('1'+1) на уровне простой C>логики должно вывести '2'.
Мы складываем-таки буквы. Букву "а" и букву "б".
Кстати, ваш пример по-моему так и отработает,в BASIC'е.
>> C>Во-первых, _каких_ юникодных char'ов? >> Тех, которые есть в языке. C>В С++ в языке есть wchar_t, для которого ничего не гарантировано (и это C>минус), можно явно использовать wchar_t как хранилище для UCS2 или C>использовать свой тип для UCS4.
Ой-ой, и вам не нравятся, что кодировки не обозначены ???
PS: вспоминается представление строк и API для работы с ними в VAX VMS :D
>> C>char c='A'; >> C>char wc=L'A'; >> puts (c + wc); ??? C>Нефиг складывать символы.
Это еще почему ??? Потому что тогда бедный C не может разобраться где у него что?
C> Кстати! Для Delphi оно тоже небезопасно: C>
C>SomeWinFunc(@'a',@'b');
C>
C>Этот код молчаливо упадет, если функция будет ожидать строку, а не символ.
Во-первых у меня обычно Typed @ включен. Так что не скомпилируется даже.
Во-вторых подмена разговора о буквах разговором про указатели... показательна.
>>> > А вот чем мешает Ord() — вопрос. >> C>Лишний мусор там, где он совсем не нужен. >> А я вот так считаю про лишний мусор там где нужно просто соединить >> два-три символа в одну строку. C>А они в какой кодировке?
зависит от компилятора/OS/настроек.
Turbo Pascal создавался для USA и там этого в принципе не было.
Думаю нетрудно будет найти компилятор C++, который ни бум-бум о кодировках. C>А с суррогатами оно работает?
Это что? MBSC ? Или чисто юникодная фишка ?
C>Что будет, если я C>сложу русский 'а' и символ в финской кодировке?
Вы не сможете их одновременно хранить в одной программе в char.
В widechar сможете, но труднее будет вывести на экран (в VCL почти нет UNICODE, увы. Проектировалась библиотека под Win3.x)
Но это проблема конкретного компилятора и библиотеки к нему. И не говоирте, что во всех компиляторах C в char можно одновременно положить русские буквы и китайские иероглифы и любая runtime library из правильно объединит.
>> C>Нет смысла выделять char в отдельный тип — без контекста (кодировки, >> C>языка и т.п.) >> А программа вероятно вне контекста работает? Такой вот сфероконь в вакууме ? C>Нет, просто для корректного выполнения даже "простых" операций типа C>сложения строк нужно знать достаточно много параметров.
Не всегда нужна поддержка одновременно сотни языков в одном экземпляре программы. Тем более была нужна в годы Turbo Pascal.
Там где нужна — можно использовать widechar. Все равно одна строка не может быть в разных кодировках одновременно и без Юникода не обойтись.
Но главное, непонятна убежденность, что если кодировки не вынесены на уровень языка — их нет и быть не может.
Я точно также могу ссказать, что вызов strcat(a,b); невозможен. Просто потому что в этом куске исходника нет нигде информации о локали. А равно и нельзя привести char к CString — по той же самой причине. Бред. Чтобы правильно отработал сhar+char нужен соотв. компилятор/рантайм который будет учитывать в какой локали программа запущена. И вопрос необходимости такого компилятора.
Насколько слыщал, в .NET все строки юникодные. Что-то мне подсказыват что компилятор ComponentPascal for .NET будет перкасно соединять русские и финские буквы. Хотя никто недогадался указывать локали в исходниках.
C>В С++ поступили честно — строки рассматриваются просто как набор байт и C>никак не интерпретируются контейнерами.
Кажется была функция добавления char к char* ? По крайней мере поиска char в char* ? Как же она-то с многобайтовыми кодировками справляется, если не знает в какой кодировке конкретный набор байт ?
Тут же выскакивают вопросы о соотношении sizeof(char) и sizeof(int) в многобайтовых кодировках, учитывая суррогаты и прочее.
C>В Паскале наоборот, выбрали некое поведение и объявили его "The Only C>Right Way".
Вам кто-то мешает сделать свой класс типа CString (за минусом операторов и дженериков) ?
>> C> с ним все равно ничего осмысленного кроме простой >> C>арифметики или сравнений выполнить нельзя. >> Как минимум — соединения. C>Нет, так как они тоже зависят от кодировок.
И что? программа работает в контексте, это не сфероконь в вакууме. Программа на этапе выполнения знает(если ей нужно) о кодировке среды и данных. Компилятор этого не знает. И не должен.
C>Имеет смысл только бинарная конкатенация,
Интересно, какой еще может быть здравый смысл у "буква + ещё одна буква" ?
C>для которой вполне достаточно арифметического представления.
Угу, достаточно. Но нужно дополнительно набивать обвязку.
А в паскале для получения кода символа нужно писать обвязку в виде Ord() — и этого тоже достаточно.
>> Можно бы было еще умножение на число определить, типа дупликации >> символов/строк C>Тоже прекрасно работают с бинарными данными.
'@'*2 что даст ? "@@" или 128 либо что-то зщависимое от кодировки ?
Если бы это было в Паскале — был бы "@@".
В C было бы как повезет, что захотелось назвать стандартом.
>> C>А для арифметики >> Угу, арифметика над буквами, я правильно понимаю? Символьная арифметика, >> прям в текстовом представлении чисел ? C>Да, для hash-контейнеров, например.
И опереторы переопределяете прям над char, над бащовым типом ?
>> Как там говорил Каганов (по памяти): Целочисленная ошибка: попытка >> деления на букву "о". C>Без проблем.
Спасибо. Предпочту без таких ошибок.
>> Никогда не видел его на уровне языка. C>Именно на уровне языка.
Вот странно-то. И почему же всегда когда надо было, я клал один тип и тут же следующим оператором доставал другой? И ни разу компилятор не удивился. И runtime тоже.
>> C>несовпадений типов (char к wchar_t не приводится без явного каста). >> И эти люди считают проблемой Ord ! C>А какое должно быть правильное поведение? Можно узнать?
Смотря что нужно. Я не считаю автоматический каст везде и всегда преимуществом или везде и всегда недостатком. Я не считаю, что иногда написать 5 буковок Ord(x) — это руки отвалятся. А вот вы так считаете. Тем более должны считать, что руки отвалятся писать (wchar_t)x — это же на целых 4 буквы больше, почти в два раза, кошмар какой.
Кстати о правильном поведениии, нет у меня Delphi 7, не интересовался. Скжау просто по здравому смыслу. Даже как-то неудобно. Вроде такие простые вещи.
Если нужно преобразовтаь char к wchar_t (widechar) — не важно, явно или автомаически — программа должна проверить в какой локали работает и исходя их этой локали преобразовfть в тот UTF, который принят (для данной программы, скомпилированной данным компилятором, работающей в данном контексте) для wchar_t.
К>Смысл сишного варианта в том, что там нет операции конкатенации как таковой и это надо понимать (и вообще по сути нет операций над массивами, которыми являются строки, как таковыми). Ну нет в си строкового типа!
Угу, а в Паскале есть. И в Паскале это имеет смысл. Но вот этого смысла и не могут простить фанаты-СИнюшники. У них видите-ли руки отвалились написать Ord. Писать strcat не отвалились, а вдвое более короткий Ord — преступление.
Здравствуйте, Arioch2, Вы писали:
К>>Смысл сишного варианта в том, что там нет операции конкатенации как таковой и это надо понимать (и вообще по сути нет операций над массивами, которыми являются строки, как таковыми). Ну нет в си строкового типа!
A>Угу, а в Паскале есть. И в Паскале это имеет смысл. Но вот этого смысла и не могут простить фанаты-СИнюшники. У них видите-ли руки отвалились написать Ord. Писать strcat не отвалились, а вдвое более короткий Ord — преступление.
Уже значит спокойно воспринимать аргументы не можем?
Обязательно переходить на обзывания?
Вопрос что рассматриваем? Если Си — это это низкоуровневый язык и там строки как первичный тип не обязательны (хотя это повод для флейма, но я не буду участвовать в нём). Если C++, то там ты можешь иметь строки любой кодировки, как ансишные, как юникодные так и другие, за программиста нет кого-то, что решает, что есть единственный The Right Way и иначе быть не может. Всёже плюсы — язык многопарадигменный и позволяющий свободнее выражать свои мысли, но это же накладывает на программиста ответственность за его решения (которые могут дать плюс, как и привести к BSOD, просто надо думать головой, а не полагаться на серебряную пулю в виде компайлера)
К>Уже значит спокойно воспринимать аргументы не можем?
Аргуметны, которые к С относятся так же как к Паскалю ?
Вот в паскале нельзя... не нравится плюс? скажаем "присовокупить" один символ кдругому, потому что неизвестна локаль. А в С можно. Хотя код вполне вероятно бужет один и тот же с точностью до представления строк (а в Coponent Pascal, где строки Сишные — может и просто без разницы).
К>Обязательно переходить на обзывания?
Фанатиков? Мы в Holywars или где ?
К> Вопрос что рассматриваем?
Ужас того, что в Паскле нужно явно кастить char в число. Именно это мне пытаются доказать. Остальное -0 побочные ответвления.
С этой точки зрения C и C++ малоотличими. char — базовый тип.
K> Если C++, то там ты можешь иметь строки любой кодировки, как ансишные, как юникодные так и другие, за программиста нет кого-то, что решает, что есть единственный The Right Way
А ассемблер еще гибче, да ?
Кто будет писать свои классы строк на C++ — тот их же напишгет на Паскале. Кому это действительно нужно.
Arioch2 wrote: >> > М.б. тогда в Watcom'е и были проверки длины *динамических* массивов, не >> > знаю. Но Watcom и стоил сколько и работал долго > C>std::vector — там он был. > А елси я в нем хотел отключить проверку ?
В векторе есть проверяемый вариант (функция at()) и непроверяемый —
оператор индекса.
> C>Ну так она имеет смысл — если обратить внимание на центр тождества. В С > C>запись A[i] значит *(A+i), а так как сложение коммутативно, то > C>*(A+i)==*(i+A)==i[A]. > Нет-нет, давай без алгебры, на пальцах. > Какой смысл все же имеет i[A], где A — например, структура.
*(i+A)
Только A — это не стурктура, а указатель на структуру. Все достаточно
логично.
> Раз уж это — преимущество C — то смысл должен быть. Иначе это тождество > получается интересной гимнастикой для умая у которой иногда случайно > бывает практическое применение.
Практическое значение имеет левая часть тождества, которая постулирует
схожесть доступа к массивам и указателям.
>> > Должно вывести на экран (на уровне простой человеческой логики) > строку "ab" > C>Почему? Мы складываем числа, например puts('1'+1) на уровне простой > C>логики должно вывести '2'. > Мы складываем-таки буквы. Букву "а" и букву "б". > Кстати, ваш пример по-моему так и отработает,в BASIC'е.
А откуда для этого взять память для результата? А если выделение памяти
будет неудачным? А какое время жизни будет у строки?
> C>В С++ в языке есть wchar_t, для которого ничего не гарантировано (и это > C>минус), можно явно использовать wchar_t как хранилище для UCS2 или > C>использовать свой тип для UCS4. > Ой-ой, и вам не нравятся, что кодировки не обозначены ???
То есть? Я же написал "можно явно использовать wchar_t как хранилище".
> C>Нефиг складывать символы. > Это еще почему ??? Потому что тогда бедный C не может разобраться где у > него что?
Может. Но попытки такой автомагической автоматизации скрывают проблемы.
> C>А они в какой кодировке? > зависит от компилятора/OS/настроек. > Turbo Pascal создавался для USA и там этого в принципе не было. > Думаю нетрудно будет найти компилятор C++, который ни бум-бум о кодировках.
_Любой_ компилятор С++ ничего не знает о кодировках строк — это не его
компетенция. Единственное, что может крутиться — это кодировка текста
программы, важная для строк, вставленных непосредственно в исходник.
> C>А с суррогатами оно работает? > Это что? MBSC ? Или чисто юникодная фишка ?
Это два символа, которые рисуются как один.
> C>Что будет, если я > C>сложу русский 'а' и символ в финской кодировке? > Вы не сможете их одновременно хранить в одной программе в char.
Да ну?
a:=chr(211);
b:=chr(211);
Угадайте, какие это символы?
> Но это проблема конкретного компилятора и библиотеки к нему. И не > говоирте, что во всех компиляторах C в char можно одновременно положить > русские буквы и китайские иероглифы и любая runtime library из правильно > объединит.
Еще раз: библиотека С работает со строками как с _бинарным_ блоком,
никак его не интерпретируя (за исключением исключений типа isupper). То
есть strcat просто объединяет два ASCIZ-блока. Поэтому для облегчения
работы 'char' и является арифметическим типом.
>> > А программа вероятно вне контекста работает? Такой вот сфероконь в > вакууме ? > C>Нет, просто для корректного выполнения даже "простых" операций типа > C>сложения строк нужно знать достаточно много параметров. > Не всегда нужна поддержка одновременно сотни языков в одном экземпляре > программы. Тем более была нужна в годы Turbo Pascal.
Ну вот, из-за узости мышления Вирта и его последователей и имеем
ситуацию, когда Delphi не заточен под i18n.
> Там где нужна — можно использовать widechar.
Тот который в Delphi — нельзя, он не поддерживает Unicode-3.
> Все равно одна строка не > может быть в разных кодировках одновременно и без Юникода не обойтись.
Да ну? Про UTF-8 слышали?
> Но главное, непонятна убежденность, что если кодировки не вынесены на > уровень языка — их нет и быть не может.
Может. Но они уже будут прикручены параллельно основной системе.
> Я точно также могу ссказать, что вызов strcat(a,b); невозможен. Просто > потому что в этом куске исходника нет нигде информации о локали.
Может. strcat объединяет бинарные блоки (о чем явно говорится в доке),
при этом не гарантируется семантическая правильность результата (о чем
тоже в доке пишется).
> Кажется была функция добавления char к char* ? По крайней мере поиска > char в char* ? Как же она-то с многобайтовыми кодировками справляется, > если не знает в какой кодировке конкретный набор байт ?
Естественно, это просто поиск арифметического значения. Без всяких
дополнительных гарантий.
> Вам кто-то мешает сделать свой класс типа CString (за минусом операторов > и дженериков) ?
А как мне сделать, чтобы для него операторы "+" работали?
> C>Имеет смысл только бинарная конкатенация, > Интересно, какой еще может быть здравый смысл у "буква + ещё одна буква" ?
`'0'+('5'-'1')`
> C>Тоже прекрасно работают с бинарными данными. > '@'*2 что даст ?
Что-то. Лень по таблице смотреть.
> C>Да, для hash-контейнеров, например. > И опереторы переопределяете прям над char, над бащовым типом ?
Нет, в частности для обобщенного кода типа:
int hash_;
add_to_hash(hash_,'a');
add_to_hash(hash_,11);
add_to_hash(hash_,112134);
> C>А какое должно быть правильное поведение? Можно узнать? > Смотря что нужно. Я не считаю автоматический каст везде и всегда > преимуществом или везде и всегда недостатком. Я не считаю, что иногда > написать 5 буковок *Ord(*x*)* — это руки отвалятся. А вот вы так > считаете. Тем более должны считать, что руки отвалятся писать > *(wchar_t)*x — это же на целых 4 буквы больше, почти в два раза, кошмар > какой.
Стоп. Какой-такой "*(wchar_t)*x" — что это должно значить?
> Кстати о правильном поведениии, нет у меня Delphi 7, не интересовался. > Скжау просто по здравому смыслу. Даже как-то неудобно. Вроде такие > простые вещи.
Они не простые, они _упрощенные_ (как в "оболваненные").
> Если нужно преобразовтаь char к wchar_t (widechar) — не важно, явно или > автомаически — программа должна проверить в какой локали работает и > исходя их этой локали преобразовfть в тот UTF, который принят (для > данной программы, скомпилированной данным компилятором, работающей в > данном контексте) для wchar_t.
Убрать слово "компилятор".
Здравствуйте, Cyberax, Вы писали:
C>Arioch2 wrote: >>> > М.б. тогда в Watcom'е и были проверки длины *динамических* массивов, не >>> > знаю. Но Watcom и стоил сколько и работал долго >> C>std::vector — там он был. >> А елси я в нем хотел отключить проверку ? C>В векторе есть проверяемый вариант (функция at()) и непроверяемый — C>оператор индекса.
И то же самое для вставки, удалении и всех прочих, да ?
А теперь, если я захочу отладив программу с проверками одним махом на куске кода их отключить?
Свой класс рисовать с виртуальными операторами? #define ? Или по всему отрезку код править? Нет, ну конечно сецчас рефакторинг развился, понимаю. Но не всегда ж так было
C>Практическое значение имеет левая часть тождества, которая постулирует C>схожесть доступа к массивам и указателям.
Ну вот на ней бы тогда и остановиться
>>> > Должно вывести на экран (на уровне простой человеческой логики) >> строку "ab" >> C>Почему? Мы складываем числа, например puts('1'+1) на уровне простой >> C>логики должно вывести '2'. >> Мы складываем-таки буквы. Букву "а" и букву "б". >> Кстати, ваш пример по-моему так и отработает,в BASIC'е. C>А откуда для этого взять память для результата?
Да хоть на стеке, компилятор решит.
C>А если выделение памяти C>будет неудачным?
Компилятор выдаст runtime error, или бросит исключение.
В отличие от C, где програмист может забыть — компилятор не забудет.
C>А какое время жизни будет у строки?
Такое, какое надо.
Я ж не спрашиваю о времени жизни
{ SomeObject var1; ..... };
,
а хоть бы (без плюсов) и
{ char buffer[200] ... };
>> C>В С++ в языке есть wchar_t, для которого ничего не гарантировано (и это >> C>минус), можно явно использовать wchar_t как хранилище для UCS2 или >> C>использовать свой тип для UCS4. >> Ой-ой, и вам не нравятся, что кодировки не обозначены ??? C>То есть? Я же написал "можно явно использовать wchar_t как C>хранилище".
Если вам не нравится, что в Паскале не задана жестко кодировка типа char, то почему вам нравится, что в стандарте C++ не задана жестко кодировка wchar_t ? Давайте определимя, должна ли быть кодировка прибита гвоздиками уже в спецификация языка или нет?
>> C>Нефиг складывать символы. >> Это еще почему ??? Потому что тогда бедный C не может разобраться где у >> него что? C>Может. Но попытки такой автомагической автоматизации скрывают проблемы.
В С, не в Паскале.
>> C>А они в какой кодировке? >> зависит от компилятора/OS/настроек. >> Turbo Pascal создавался для USA и там этого в принципе не было. >> Думаю нетрудно будет найти компилятор C++, который ни бум-бум о кодировках. C>_Любой_ компилятор С++ ничего не знает о кодировках строк — это не его сразу замечу: runtime library считаю неотъемлемой частью компилятора, с практической точки зрения, при разборе того, как работает конкретная уже откомпилированная программа. C>компетенция. Единственное, что может крутиться — это кодировка текста C>программы, важная для строк, вставленных непосредственно в исходник.
Та же фигня в Паскале. Почему же в случае Паскаля это претензия, а в случае C — нет? Что за двойной стандарт ?
>> C>А с суррогатами оно работает? >> Это что? MBSC ? Или чисто юникодная фишка ? C>Это два символа, которые рисуются как один.
Так все-таки, рчь идет о юникоде или нет?
могу я суррогат+букву запихнуть в Cшный char или нет ?
>> C>Что будет, если я >> C>сложу русский 'а' и символ в финской кодировке? >> Вы не сможете их одновременно хранить в одной программе в char. C>Да ну? C>
C>a:=chr(211);
C>b:=chr(211);
C>
C>Угадайте, какие это символы?
Гадать не нужно, нужно узнат в какой кодировке работает программа. Такой это символ и будет.
Программа работает в каком-токонтексте а не на абстрактной идеальной машине.
C>Еще раз: библиотека С работает со строками как с _бинарным_ блоком, C>никак его не интерпретируя (за исключением исключений типа isupper).
А Паскалевская не так ?
C>есть strcat просто объединяет два ASCIZ-блока.
А Паскалевская — две паскаль-строки.
C>Поэтому для облегчения C>работы 'char' и является арифметическим типом.
вот тут я не понимаю.
А что, будь он буквой, *dst = *src работало бы хуже? Или memcpy бы работало хуже?
>> программы. Тем более была нужна в годы Turbo Pascal. C>Ну вот, из-за узости мышления Вирта и его последователей
Стоп. Не нужно примешивать Вирта к Borland. C>и имеем C>ситуацию, когда Delphi не заточен под i18n.
Более того, речь идет не о языке ,а о конкретной библиотеки очень тесно привязанной к Win API
Был бы в Win16 API юникод — было бы по-другому.
>> Там где нужна — можно использовать widechar. C>Тот который в Delphi — нельзя, он не поддерживает Unicode-3.
Насколько знаю, он использует функции Win API, и должен поддерживать все, что WinAPI.
>> Все равно одна строка не >> может быть в разных кодировках одновременно и без Юникода не обойтись. C>Да ну? Про UTF-8 слышали?
тогда выбирайте, что именно вы сказали:
1) UTF-8 — не Юникод.
2) UTF-8 — не кодировка.
>> Но главное, непонятна убежденность, что если кодировки не вынесены на >> уровень языка — их нет и быть не может. C>Может. Но они уже будут прикручены параллельно основной системе.
...если нужна совместимость назад, с не-Юникодом. Она была нужна.
В C наверное тоже не просто так char и wchar_t разные типы ? Параллельные.
>> Я точно также могу ссказать, что вызов strcat(a,b); невозможен. Просто >> потому что в этом куске исходника нет нигде информации о локали. C>Может. strcat объединяет бинарные блоки (о чем явно говорится в доке),
А a+b объединяет строки, и о том явно говорится в доке.
И *работающая* программа знает в какой кодировке она работает.
Кроме того, когда это бинарное объединение строк может дать неправильный результат ?
Когда первая строка кончается на одинакий суррогат, не имеющий основной буквы к нему?
Так такая строка уже семантически не верна.
Garbage in — garbage out.
C>Естественно, это просто поиск арифметического значения. Без всяких C>дополнительных гарантий.
Это вам они дополнительные, а где-то они нужны.
>> Вам кто-то мешает сделать свой класс типа CString (за минусом операторов >> и дженериков) ? C>А как мне сделать, чтобы для него операторы "+" работали?
Повторяемся. Нету в паскале дженериков и пергрузки оператора.
Кроме того — зачем? Кроме синтакического сахара ?
Сделайте лучше перегруженную strcpy (CString&, CString&) и не заимствуйте вы этот дурацкий паскалевский плюс.
>> C>Имеет смысл только бинарная конкатенация, >> Интересно, какой еще может быть здравый смысл у "буква + ещё одна буква" ? C>`'0'+('5'-'1')`
Отрицание не имеет смысла над строками.
>> C>Тоже прекрасно работают с бинарными данными. >> '@'*2 что даст ? C>Что-то. Лень по таблице смотреть.
Тогда заканчиваем с экспериментами. умножение деление и отрицание над буквами/строками не определены
Но в случае Паскаля умножение было бы легче определить.
>> C>Да, для hash-контейнеров, например. >> И опереторы переопределяете прям над char, над бащовым типом ? C>Нет, в частности для обобщенного кода типа: C>
Если эти базовые типа имеют автоматическое приведение к типу T, так ?
Учитываем нелюбовь паскаля к автоматическим кастам — и делаем ручное преобразование.
Учитываем отсутствие прергрузки операторов, и заменяем += на по сути эквивалентное _cur.Add(_param);
Ну опять же, нет дженериков пока, первый скажу, хотя повторяться надоедает.
Разница — синтаксический сахар.
>> C>А какое должно быть правильное поведение? Можно узнать? >> Смотря что нужно. Я не считаю автоматический каст везде и всегда >> преимуществом или везде и всегда недостатком. Я не считаю, что иногда >> написать 5 буковок *Ord(*x*)* — это руки отвалятся. А вот вы так >> считаете. Тем более должны считать, что руки отвалятся писать >> *(wchar_t)*x — это же на целых 4 буквы больше, почти в два раза, кошмар >> какой. C>Стоп. Какой-такой "*(wchar_t)*x" — что это должно значить?
А это где-то кому-о взглюкнулось, вместо звездочек там (b) и (/b) — все кроме переменной выделенно жирным шрифтом.
C>Они не простые, они _упрощенные_ (как в "оболваненные").
Да нет, там просто нет ненужной сложности. Кому она нужна — добавит.
>> Если нужно преобразовтаь char к wchar_t (widechar) — не важно, явно или >> автомаически — программа должна проверить в какой локали работает и >> исходя их этой локали преобразовfть в тот UTF, который принят (для >> данной программы, скомпилированной данным компилятором, работающей в >> данном контексте) для wchar_t. C>Убрать слово "компилятор".
Почему? У нас таки абстрактные сферокони, которых компилируют абстрактные компиляторы ?
Здравствуйте, Larev, Вы писали:
DH>>но единственная фича которая перевесила в пользу си — это возможность обьявлять переменные в произвольном месте , а не где-то там, в блоке var.
L>Это конечно супер, но злоупотреблять этим не стоит. Иной раз хорошо объявить переменную внутри блока, но чрезмерный разброс объявлений переменных затрудняет чтение кода, да и это не очень хороший тон. Желательно объявления переменных группировать "кучками" в логически правильных местах.
А может лучше создавать такие методы, которые помещаются целиком на экран, тогда и группировать "кучками" не придется. У нас есть сотрудники, которые умудряются запихнуть весь код в одну функцию, длиной в несколько тысяч строк! Вот у них есть такой маразм, объявлять все используемые переменные в начале функции.
Здравствуйте, s.ts, Вы писали:
ST>продолжение из моего опыта:
ST>... но как выяснилось, большинство пишущих на с++ пишут на нем в стиле плохого дельфи-кодераочень многие не могут даже на паскале нормально написать (как выразился один мой коллега-дельфин: "тут ведь если компилируется, то работает!" — это про паскаль конечно). Люди, пишущие на C++ не знают stl, не используют шаблоны и нэймспэйсы, создают кучу глобальных переменных, называя их MyVar и ... вообще, даже страуструпа похоже не читали. ST>зато все мегабаксовые вакансии с работных сайтов с гордыми заголовками "С++" для них. и рекрутеры пытаются выудить из потока г... ST>мнда...
ST>добавлю в заклюении, то все встретившиекся в моей жизни дебилы от программирования (кроме одного ) писали на С++
Да, есть такие, которые гордо заявляют, что могут писать как на Делфи так и на С++ одинакого, но это только говорит о том, что они не знают ни того, ни другого даже на троечку.
Здравствуйте, Кодёнок, Вы писали:
Кё>interface в Borland Pascal 100% инкапсуляцию тоже не обеспечивает. И зачем оно? Напусти на исходник простой процессор, и он выдаст вам .int — файл, где есть действительно только интерфейсная часть. В компиляции такой файл все равно не участвует. А вот дублирование заголовков функций в interface и implementation сильно портит жизнь. Поменял определение — ищи в большом файле реализацию. Приходилось мне поддерживать и дорабатывать код на Delphi, так что я очень злой на эту фигню
Не знаю как в паскале, а в дельфи как раз заголовки в interface и implemintation не обязательно дублировать.
interface
function Test(Param: string): Integer;
implementation
function Test;
begin
Result := MessageBox(0, PChar(Param), nil, 0);
end;
так что не злится надо было, а изучать инструмент, который ты пользуешь.