[programming] Женская логика
May. 21st, 2003 06:19 pmЗадачка для знатоков C++ и Unicode. Компилим код, содержащий следующий кусочек, с помощью MSVC6/SP6 на машине с Windows 2000 и ANSI codepage 1251. Вопрос: что выдаст printf? Для справки: U00C5 есть "Å".
wchar_t* pszLatin1String = L"\x00C5";
printf("U%04X\n", (unsigned int) *pszLatin1String);
Вы усцытесь, но выдано будет U0415, сиречь код русской буквы "Е".
То бишь, анализатор MSVC выделяет лексему \x00C5, внимательно смотрит на неё и решает — раз значение восьмибитное, хер с ним, с контекстом юникодного строкового литерала, давайте преобразуем это восьмибитное значение в Юникод, используя текущий пользовательский codepage. А C5 в CP1251 отображается, само собой в U0415, CYRILLIC CAPITAL LETTER IE. Что и попадает в результате в юникодную константу.
Subj?
"C++ Lexical Conventions" в MSDN, разумеется, ничего такого не говорит. Читать стандарт не пойду, потому что просто противно.
no subject
Date: 2003-05-21 07:25 am (UTC)no subject
Date: 2003-05-21 07:26 am (UTC)Литерал-то, блин, юникодный! Какой locale?! Эх…
no subject
Date: 2003-05-21 07:41 am (UTC)-- Ты суслика видишь?
-- Нет!
-- И я -- нет. А он -- есть!
#pragma setlocale(".1251")
wchar_t* pszLatin1String = L"\x00C5";
printf("U%04X\n", (unsigned int) *pszLatin1String);
#pragma setlocale(".1252")
pszLatin1String = L"\x00C5";
printf("U%04X\n", (unsigned int) *pszLatin1String);
Печататет:
U0415
U0435
no subject
Date: 2003-05-21 07:46 am (UTC)no subject
Date: 2003-05-21 12:28 pm (UTC)wchar_t со звездочкой. Офигеть! кого волнует wchar?..
ужасный язык :)
no subject
Date: 2003-05-21 11:25 pm (UTC)no subject
no subject
no subject
Date: 2003-05-22 12:43 am (UTC)no subject
Date: 2003-05-22 12:46 am (UTC)no subject
Date: 2003-05-22 12:51 am (UTC)no subject
Date: 2003-05-21 08:00 am (UTC)(А в java такого не происходит никогда, под любой локалью :-)
no subject
Date: 2003-05-21 08:11 am (UTC)Происходящее выше безобразие происходит на этапе лексического анализа. Неразличение int и char тут IMHO ни при чём.
А так — как раз вчера мы с Андреем пришли к выводу, что лучшим в мире языком программирования могла бы стать Java со слегка усовершенствованным си-плюс-плюсным memory management'ом, то бишь, без GC, со свободой создавать что угодно на стеке или в куче, и нормальными деструкторами.
no subject
Date: 2003-05-21 08:27 am (UTC)Охотно допускаю, что я неправ.
Совсем без GC грустно %-) Но и с одним GC грустно. Хорошо бы иметь возможность создавать *некоторые* объекты с контролируемым временем жизни (и соотв. "нормальными деструкторами"). Хотя бы локальные переменные с ограниченным scope, как это вроде бы есть в C#: вышел из scope, и указанные объекты гарантированно померли. Ессно, компилятор гарантирует, что не допустит "утекания" ссылки за scope, etc.
no subject
Date: 2003-05-21 11:47 pm (UTC)Мне-то казалось, что оно как хранилось в виде 0xc5, так и хранится.
Там литерал был юникодовский, то бишь, начинающийся на букву L. Хранится он безусловно 16-битно. Проблема случается именно при парсинге исходного текста.
no subject
Date: 2003-05-22 12:45 am (UTC)Хорошо бы иметь возможность создавать *некоторые* объекты с контролируемым временем жизни.
Богатая, кстати, наклёвывается тема. Допустим, мы заводим две кучи, одну garbage collected, для ленивых, другую традиционную, для тех, кто знает, чего делает. Интересный вопрос: размещение в той или иной куче должно быть атрибутом класса (e.g.
public gc class MyGarbageCollectedClass {…}) или экземпляра (e.g.MyGarbageCollectedInstance = new gc SomeClass;)? Тот же вопрос применим и к размещению в стеке (то, что ты называешь "с ограниченным scope").Я лично думаю, что это стоило бы сделать атрибутом класса, ибо деструктор, например, при сборке мусора теряет всякий смысл. Будут ли другие мнения?
Ещё одна видимая опция: операция типа boxing/unboxing для перехода между типами размещения.
Вообще, надо бы подробнее перетереть.
no subject
Date: 2003-05-22 02:04 am (UTC)Это, однако, мешало бы использовать один класс (скажем, из базовой библиотеки коллекций) и с gc, и без. Тут выхода два: либо легко делаемый по месту anonymous class (всего-то написать деструктор, скорее всего, в один вызов готового метода), либо какой-то boxing/unboxing, но какой, я не представляю %-)
А иметь такую возможность хочется, чтобы писать что-то вроде
{ scope_only File f = new File(); // или new File() implements ExplicitlyManaged { void destruct() {close();}} f.open('filename'); bar(f); f.close(); } // и в этой точке f гарантированно прибиваетсяИнтересно, что делать, если надо не-gc-шный объект убить, а ссылки на него ещё есть. Либо бросать exception при убивании (тогда дорогостоящая проверка на наличие ссылок), либо имеющиеся ссылки на него обрабатывать как weak references сейчас, т. е. бросать исключение при обращении, если объект ссылки уже умер: тут даже особо переделывать ничего не придётся.
Ещё хорошо бы иметь несколько независимых куч и возможность говорить
Foo my_foo = new Foo(1) on that_heap_of_mine;
Ради того, чтобы можно было говорить в нужный момент that_heap_of_mine.gc() -- если куча эта небольшая (я ж сам контролирую, что в ней завожу), то и gc пройдёт быстро и хоть как-то контролируемо. Вопрос, конечно, совместимо ли это с применяемыми нынче алгоритмами gc.
(Похожая фича с многими кучами была в движке Doom.)
no subject
Date: 2003-05-21 07:53 am (UTC)VC6 есть догма?
Date: 2003-05-21 08:37 am (UTC)На первом уже с полгода наверное работаем, перешли с шестерки, практически никаких претензий. На 7.1 пока сижу только я один, но тоже претензий нет, а компилятор стал еще лучше.
Re: VC6 есть догма?
Date: 2003-05-21 11:24 pm (UTC)2. Кто-нибудь может объяснить тот забавный факт, что драйвера можно собирать только VC 6.0?
Re: VC6 есть догма?
Date: 2003-05-21 11:45 pm (UTC)Хм-с ...
Date: 2003-05-22 12:16 am (UTC)2. Никогда не писал драйвера, увы. Может дело в библиотеках? Ибо приложения, собранные 7.* требуют .Net dll-к (нам сам .Net на клиентские места ставить не понадобилосб). Кстати, а что, драйвера уже на С++ пишут?
Re: Хм-с ...
Date: 2003-05-22 12:32 am (UTC)2. Драйвера, очевидным образом, пишутся без использования стандартной RTL компилятора. Там для этого системная RTL есть. И, кстати, статическую линковку еще никто не отменял. Что же до драйверов на C++ -- а какая, собственно, разница, на C писать или на С++, покуда компилятор один.
Хм-с 2 ...
Date: 2003-05-22 12:52 am (UTC)2. Если и с первым беда, то я просто боюсь предположить что народ умудрится начудить с плюсами ...
Re: Хм-с 2 ...
Date: 2003-05-22 01:02 am (UTC)Да, есть. Но это уже другой вопрос.
Date: 2003-05-22 01:25 am (UTC)С 7-кой что хорошо, сорри что сразу не написал, она замечательно уживается с 6-кой на одной машине, поэтому какое-то время мы просто параллельно поддерживали проектники для них обоих, до сих пор вроде как в cvs-е валяются.
Скрещивать приложения на 7-ке с библиотеками, собранными 6-кой особо не приходилось, но однако Qt, с которой начинали работать еще под 6-кой, нормально используется и под 7-кой.
Re: Да, есть. Но это уже другой вопрос.
Date: 2003-05-22 01:37 am (UTC)10x 4 info :)
Date: 2003-05-22 10:52 am (UTC)По поводу портирования: GNU c++ и VC++ 6 можно заставить правильно компилить одно и то же, но не сразу :) Как я не раз замечал, порт gpp -> VC на порядок проще, чем в обратную сторону (если, конечно, в коде нет чего-то, что не поддерживается в VC6, вроде вложенных шаблонов)