C++

Я ваш Adobe DNG SDK труба шатал!

Продолжаю биться головой о стену DNG SDK .

Вот, к примеру, объявление функции

void dng_negative::SetStage1Image (AutoPtr<dng_image> &image);

Вот как я обычно делаю:

// MyClass.h class dng_image; // Никаких include "dng_.....h", просто forward declaration class MyClass { private: dng_image *image; };

И только там, где у меня implemetation для MyClass - там будет включено "dng_image.h" и мы, наконец, разберемся, что же это такое (а указатель... ну указатель, 4/8 байт, нечего про него знать, private)

Но если интерфейс у dng_negative требует AutoPtr<>,...

С++: invalid initialization of non-const reference of type 'foo&' from an rvalue of type 'foo'

Вот представим себе такой вот зачин:

class foo
{
public:
 foo(int aa, int bb) : a(aa),b(bb){}
 int A() { return a;}
 int B() { return b;}
private:
 int a,b;
};

int func(foo& f) { return f.A()*f.B();}
Почему передача по reference? Ну это, типа, дешевле. Для структуры из двух полей вероятно плевать, а если там std::string содержащий "Войну и Мир"? При передаче по значению оно же должно скопироваться?

А теперь пытаемся это использовать:

int main()
{
    return func(foo(1,2));
}
g++ (4.6, если важно) ругается и говорит:
error: invalid initialization of non-const reference of type 'foo&' from an rvalue of type 'foo'
А Visual Studio 2010 жрет нормально.

Об исключениях (C++)

Я не люблю C++-ные exceptions (за второй поток управления), как следствие - стараюсь их не использовать, а если использую, то перехватываю только те, которые порождает мой код. Как следствие, правил хорошего тона в этой области не знаю.

Возник вопрос, как правильно поступать. Вот есть такой примерно код:

int some_class::some_function(std::filebuf& buf)
 
  try {
      ....
      buf.sgetn(....);
      .....
      return 0; // OK
  }
  catch (my_own_exception_type t) {
        аккуратно_склеить_ласты();
        return errorcode;
   }
}
Вопрос: должен ли я в подобном коде ловить исключения, порожденные std::filebuf? Ну там не смог он ничего прочесть? А вообще все исключения? Как требуют понятия хорошего тона?

Должны ли быть эти правила хорошего тона разными в таких двух случаях

  • Этот самый std::filebuf - на самом деле хранится внутри класса, где-то раньше был создан/открыт и все такое. То есть это наш сукин сын.
  • Этот самый IO-хэндл (std::filebuf) передан нам снаружи т.е. это чужой сукин сын.
?

P.S. Нашелся йузер у которого для файлов с SD-читалки не работает std::filebuf IO. Linux, холст, масло....

О семантике C++

В продолжение кулуарного разговора с Highload++, навеянного 26-м слайдом презентации Андрея Аксенова.

Вот такой вот код:

class someShit{
        char *m_sBuffer;
        size_t m_iLimit, m_iCounter;
};
void someShit::try1()
{
        m_iCounter = 0;
        while (m_iCounter< m_iLimit && m_sBuffer[m_iCounter])
                m_iCounter++;
}

void someShit::try2()
{
        size_t l_iCounter = 0;
        while (l_iCounter< m_iLimit && m_sBuffer[l_iCounter])
                l_iCounter++;
        m_iCounter = l_iCounter;
}
Компиляторы (смотрел gcc 4.6, Visual Studio 2010 и Intel 11.0, все с включенной стандартной оптимизацией -O3/O2 без тонких настроек) делают разное:
  • gcc и Visual Studio генерируют код с той семантикой, какой написано;
  • Intel C++ делает так же, если компилирует "библиотеку", но оптимизирует первый случай до второго, если все потроха (методы класса и вызывающий их main()) лежат в одном файле.

C++ streams compatibility...

Граждане программисты,

Я - человек темный, граблями причесываюсь на фортране-77 все еще программирую. Но мне пишут, что дескать в современных C++-стримах все сделано по уму в смысле буферизации и работают они временами сильно быстрее, чем любимый мой FILE*

Собственно, сомневаться причин нет, в тестах так оно и получилось (и разница заметная), но мучает меня вопрос с совместимостью.

Мою LibRaw на чем только не собирают, вот даже на Maemo, а давеча я проблемы с Visual Studio 2003 правил.

Отсюда вопросы (сам я за всем этим не слежу, проще спросить):

  • Интерфейс то стримовый за последние лет 7-10 - он вообще как, стабилизировался?
  • Следует ли ожидать всяких открытий чудных, вроде того что метод есть, но не работает?
  • С Linux/Mac проблем нет, я вижу что в gcc 4.x все (на первый взгляд) нормально. А что с виндами, причем как в ипостаси Visual Studio, так и cygwin/MinGW? Может есть какая-то табличка по совместимости хотя бы по Visual C++

Ужасы программирования

Сортирую записи по 8-байтным ключам в byte order (не в numeric). Записей много (сотни миллионов). Оказывается, сравнивать ключи надо так:

    unsigned char *p1 = (unsigned char *)d1;
    unsigned char *p2 = (unsigned char *)d2;
#define CMP(i) if(p1[i]!=p2[i]) return p1[i]-p2[i]
    CMP(0); CMP(1); CMP(2); CMP(3); CMP(4);CMP(5); CMP(6); CMP(7);
    return 0;
#undef CMP

А банальный memcmp/__builtin_memcmp оказывается в 2.2 раза медленнее на общее время исполнения qsort(), во сколько раз различается сравнение - боюсь думать.

С numeric-сортировкой тоже весело, естественно наступил на (value2-value1) - это быстро и неверно (а верный вариант - получился не быстрее побайтового).

Обожаю язык C++

cd STLport-5.1.5/build/test/unit
gmake -f gcc.mak all-static 2>build.error >build.log

Получаю одно (!) сообщение об ошибке, размер сообщения 795 килобайт.

Subscribe to C++