вторник, 23 марта 2010 г.

Effective C++ compiler

Кстати, пока смотрел флаги GNU C++ в предыдущем сообщении, наткнулся на флаг -Weffc++. Он говорит компилятору сообщать о нарушениях правил Скота Мейерса(Scott Meyers) из книг Effective C++ и More Effective C++. Контролируются следующие правила из первой книги:

11. Для классов с динамическим выделением памяти объявляйте копирующий конструктор и оператор присваивания.
12. Предпочитайте инициализацию присваиванию в конструкторах.
14. Делайте деструкторы виртуальными в базовых классах.
15. "operator=" должен возвращать ссылку на *this.
23. Не пытайтесь вернуть ссылку, когда вы должны вернуть объект.

И следующие из второй:

6. Различайте префиксную и постфиксную формы операторов инкремента и декремента.
7. Никогда не перегружайте опреаторы "&&", "||", и ",".

Хочу такую фичу в Visual Studio.

Сколько яблок у Маши?

Вопрос: У Миши было 5 яблок.
Два яблока он отдал Маше.
Сколько стало у Маши?
Ответ: Неизвестно. Нужно
инициализировать переменные.

Сегодня столкнулся с тем, что в релизе программа не работала, а в дебаге выполнялась вполне корректно. Причины могут быть разными, но первое что нужно проверять — это все ли переменные инициализированы. Интересно, что в Visual Studio нет никакого предупреждения с /W4 и флагом /analyze. В приведенном ниже примере компилятор нашел только одну проблему:
#include <iostream>
using namespace std;

struct  X
{
    int x;
};

struct Y
{
    int y;

    Y() {}
};

int main()
{
    X x;
    Y y;
    int ly = y.y; // не ловит
    int lx = x.x; // warning C6001: Using uninitialized memory 'x': Lines: 19, 20, 21, 22
    cout << ly << endl << lx << endl;
}
Из других компиляторов, которые я попробовал ошибку поймал только GNU C++ с флагом -Wuninitialized. Comeau С++ и Intel C++ поймали только одну ошибку. А мне казалось, что такие простые вещи уже научились ловить все приличные компиляторы...

понедельник, 22 марта 2010 г.

MS In. Day

Микрософтский форум компаний-разработчиков Microsoft Innovation Day пройдет 26 марта в Москве. Поеду послушать про новые возможности Microsoft SQL Server 2008 R2. Если кому интересно, то посмотреть полную программу мероприятий и зарегистрироваться можно здесь. Участие бесплатно.

четверг, 11 марта 2010 г.

Cake with greeting

Что можно написать на торте для технически подкованного друга или подруги? Изобретательные айтишники предлагают следующую формулу: $$r = \frac{\sin\varphi\sqrt{\left|\cos\varphi\right|}}{\sin\varphi+\frac{7}{5}}-2\sin\varphi+2$$ Если сразу вообразить график функции не получается, то можно посмотреть в WolframAlpha или ниже:

среда, 3 марта 2010 г.

endl effect

При разработке часто используют вывод отладочной информации в лог файлы. В простейшем случае это может выглядеть вот так:
ofstream_log_file_ << 
  "Add useful debug message here " << 
  extra_info_ << std::endl;
В этом коде вызывается функция std::endl, которая помимо перевода строки для буферезированных потоков сбрасывает буфер в выходной файл. При небольшом количестве таких вызовов это даже полезно — в случае падения программы в логе останется полезная информация. Но для интенсивного логгирования, когда нужно писать в лог очень часто, эта дополнительная особенность снижает скорость в несчитанное количество раз.

Ускорить запись в лог очень просто — меняем std::endl на известный символ "\n".
ofstream_log_file_ << 
  "Add useful debug message here " << 
  extra_info_ << "\n";

вторник, 2 марта 2010 г.

Explicitly qualified name

Вчера наткнулся на интересную проблему. Рассмотрим следующий пример:
std::string convert();
// ...
namespace tools {
class Numeric {
// ...
friend std::string ::convert();
};
}
При компиляции этого кода компилятор выдает ошибку. Что тут не так и как исправить положение? Ответ и пояснение чуть позже.



Ошибка тут в том, что компилятор парсит этот код как std::string::convert, как правильно заметил ztonix в комментариях. К сожалению избавиться от :: нельзя, т.к. без точек мы декларируем функцию tools::convert и пометим её как friend.

Решением проблемы будет использовать скобки для выделения имени функции:
friend std::string (::convert)();
Стоит отметить, что со встроенными типами таких проблем нет. Компилятор однозначно воспринимает friend int ::convert();