пятница, 23 апреля 2010 г.

Pointer to mutable member

Указатели на члены класса позволяют обращаться с членами класса не зная их имени.
struct S {
int i;
};

int S::* pm = &S::i;
Далее эти указатели можно использовать следующим образом:
S cs;
cs.*pm = 10;
Интересно, что нет никакого специального синтаксиса для переменных с квалификатором mutable. Более того, стандарт запрещает использовать указатель на mutable член класса для модификации константного объекта класса (C++ Standard 5.5/5). Следующий код не будет компилироваться:
struct S {
mutable int i;
};
const S cs;
int S::* pm = &S::i; // pm refers to mutable member S::i
cs.*pm = 88;         // ill-formed: cs is a const object
Запрещено это было, видимо, т.к. компилятору сложно отслеживать на какой именно член класса указывает pmmutable или нет. Как и большинство других, это ограничение можно обойти создав обертку:
template<typename T> struct mutable_wrapper { mutable T value; };
Далее используем следующим образом:
struct S {
mutable_wrapper<int> i;
};

const S cs;
mutable_wrapper<int> S::* pm = &S::i;
(cs.*pm).value = 88;
В обертке можно перегрузить операторы приведения типа, чтобы синтаксически скрыть обертку, но это дела вкуса. На мой взгляд лучше явно видеть, когда модифицируются mutable члены класса.

вторник, 20 апреля 2010 г.

in_addr visualizer

Странно, что в Visual Studio нет готового визуализатора для типа in_addr. Я поудивлялся и написал свой:
in_addr {
preview
(
#( "[ ",
[$e.S_un.S_un_b.s_b1,u], ".",
[$e.S_un.S_un_b.s_b2,u], ".",
[$e.S_un.S_un_b.s_b3,u], ".",
[$e.S_un.S_un_b.s_b4,u],
" ]"
)
)
}
Его нужно добавить в файл autoexp.dat. Тогда структура in_addr в отладчике будет выглядеть как [ XXX.XXX.XXX.XXX ]. Удобно также смотреть адреса, которые прячутся в типах long написав в окне Watch (in_addr*)&address. Тогда вместо 990554304 получаем [ 192.168.10.59 ].

После изменения autoexp.dat студию нужно перезапустить (иногда работает без перезапуска).

пятница, 16 апреля 2010 г.

Песенка для запоминания π

Искал в инете число $\pi$ с большой точностью. Наткнулся на милую песенку тут. Смотреть со звуком.

Кстати, число с нужной точностью нашел тут.

пятница, 9 апреля 2010 г.

sizeof char и другие сложности с типами

Составил таблицу с размерами типов в различных компиляторах и операционных системах (32- и 64-битных). Это полезно знать, чтобы учитывать при проектировании переносимых решений. Также полезно знать, что лучше использовать типы фиксированной длины. В новых версиях стандарта (начиная с C++11) для этого имеется файл stdint.h. Аналогичный файл существует и для языка C. Для более старых версий можно использовать pstdint.h. А использование в интерфейсах модулей знаковых типов фиксированной длины, позволяет относительно легко стыковаться с модулями на других языках, которые написаны в соответствии с Common Language Specification.

ТипMSVC++
32-bit
MSVC++
64-bit
gcc++ 4.4.1
32-bit
gcc++ 4.7.2
64-bit
char1111
short2222
int4444
long4448
size_t4848
wchar_t2244
long long8888
time_t18848

1) В версии MSVC++ старше 2005 time_t был определен как long int (32 bits) и поэтому не мог использоваться для дат позднее 19 января 2038 3:14:07 UTC. Начиная с Visual C++ 2005 time_t стал эквивалентен __time64_t по умолчанию, но это поведение можно изменить определив _USE_32BIT_TIME_T (тогда time_t будет определен как __time32_t). В таблице показан размер time_t по умолчанию.

четверг, 8 апреля 2010 г.

Сравнение поддержки C++0x в GNU C++ и MSVC++2010

Скот Мейерс(Scott Meyers) опубликовал сравнение поддержки стандарта C++0x в GNU C++ и Visual Studio. Исследование включает также стандартную библиотеку. Сравниваются g++ 4.3, g++ 4.4, MSVC++ 9 и MSVC++ 2010 Beta 2. Посмотреть можно здесь.