Undefined Behavior для C разработчиков

Очень интересная серия статей посвященных Undefined Behavior от Криса Чембера, одного из авторов LLVM.
What Every C Programmer Should Know About Undefined Behavior #1/3
What Every C Programmer Should Know About Undefined Behavior #2/3
What Every C Programmer Should Know About Undefined Behavior #3/3

Странные собеседования

В последнее время мне “везет” на странные собеседования. Чтоб было понятнее о чем я говорю, странные собеседования отличаются от нормальных неким неожиданным волшебным поведением противоположной стороны. Итак, пообщался я с R&D подразделением одного крупного американского банка, сидящим в солнечном “бананово лимонном” и гордым маленьким стартапом из не менее солнечной Калифорнии. Что довольно важно, или может на оборот, не важно, менеджеры принимающие итоговое решение были русские.
Continue reading

Инициализация статического объекта в GCC

С удивлением узнал о том, что GCC гарантирует атомарность создания статического объекта. Поэтому следующий код будет корректен в многопоточном окружении:

template <typename T>
T& singleton()
{
    static T obj;
    return obj;
}

Если по каким-то причинам такое поведение кажется возмутительным, можно воспользоваться флагом -fno-threadsafe-statics

Кстати, кто знает как обстоят дела с инициализацией статических объектов у других компиляторов?

Легенда о константной ссылке.

Уже несколько раз в кругах C++ разработчиков слышал Легенду о константной ссылке. Легенда варьируется от “из функции можно вернуть константную ссылку на временный объект” до “можно сохранить константную ссылку на временный объект”. Как раз на прошлой неделе мы обсудили этот вопрос с коллегами, и мне захотелось в нем детально разобраться.
В стандарте данная ситуация освещена очень вскользь, так что пришлось покопаться. Во-первых, в пункте 12.2.5 сказано следующее:
Continue reading

Получаем стек вызовов в Mac OS X

Я давно хотел добавить поддержку получения стека вызовов к своему Tasks Explorer, но никакой публичной информации на этот счет мне не попадалось, а ковырять систему было некогда да и лень (зима, чтоб ее). С первыми лучиками весеннего солнца задача с получением стека вызов стала казаться не такой уж и скучной и дело сдвинулось.
Начал я с того, что нашел утилиту stackshot разработки Apple, только вот исходники приложения закрыты. Как вариант, stackshot можно было использовать напрямую, но в целом такая идея мне не понравилась, да и никаких новых и полезных знаний это не даст. Тем не менее, stackshot вполне сгодился в качестве отправной точки.
Continue reading

C++ man(3)

Давно хотел разжиться маном по плюсам ибо задрало лазить в инет за этой информацией.
Подходящий ман берется вот тут: ftp://ftp.gwdg.de//pub/misc/gcc/libstdc++/doxygen/
И копируется вот сюда: /usr/share/man/man3
Ну а если к Vim-у добавить вот этот плагин, жизнь становится еще прекраснее :)))

cURL & Proxy & HTTPS & Authorization == CURLE_RECV_ERROR

Да, баги в тулзах преследуют меня всю неделю. На сей раз отличился cURL с древним багом связанным с запросом отправляемым по HTTPS через прокси. Похоже что ситуация не слишком распространенная, т.к. надо не только работать через прокси, но еще на прокси должна быть включена авторизация и при отправке запроса пароль должен быть не указан. В принципе, в такой ситуации ожидаешь код 407, просишь пользователя ввести пароль и наступает счастье. Но вот cURL думает иначе. Вместо того чтоб вернуть 407 и страничку с ошибкой от прокси, которые судя по его логу присутствуют, зачем-то возвращается CURLE_RECV_ERROR.

Ignore 1380 bytes of response-body
Received HTTP code 407 from proxy after CONNECT
Closing connection #0
Failure when receiving data from the peer

Какого-либо корректного выхода из данной ситуации я не нашел. Так что, при работе через прокси, если пароль не задан и возникает ошибка CURLE_RECV_ERROR, единственное что остается – повторить запрос, предварительно указав параметры авторизации на проксе.

LLVM, чтоб его.

Баг 2008 года в LLVM портит мне жизнь. Берем тестовый файлик следующего содержания:

class RPC_Service
{
public:
  virtual ~RPC_Service ();
};
class EventLoggingInterface
{
  virtual void
    Ev (const char *file, int line, int sev, const char *fmt,
        ...) const = 0;
};
class RPCCore : RPC_Service, EventLoggingInterface
{
  virtual void
    Ev (const char *file, int line, int sev, const char *fmt, ...) const;
};
void
RPCCore::Ev (const char *file, int line, int sev, const char *format, ...) const
{
}

Выполняем команду:

/Developer/usr/bin/llvm-g++ thunk_error.cpp -c

И в результате получаем:

thunk_error.cpp:19: error: generic thunk code fails for method ‘virtual void RPCCore::Ev(const char*, int, int, const char*, ...) const’ which uses ‘...’

Неужели придется отказаться от LLVM? Интерфейс, в моем случае, поменять врятли удастся. Вобщем писать кроссплатформенный код это еще та засада

Квалификатор restraint

Последнее время я довольно много пишу на Си, да чистое Си, без никаких плюсов, обджектив и прочей радости. На первый взгляд, в Си все очень и очень просто. Но, как оказалось, это только кажется, на том же BrainBench в тесте по Си мне удалось набрать всего 3.25, против 4.34 по плюсам. А еще говорят что BB ни о чем не говорит, говорит и еще как
А вступление это вот к чему. Я решил написать небольшую серию заметок про Си, если говорить точнее, то про C99. Ведь лучший способ что-то запомнить – это написать.
В состав C99 был добавлен новый квалификатор типа – restraint.
Данный квалификатор используется применительно к указателям и говорит компилятору о том, что данные, на которые указывают такие указатели, не являются пересекающимися объектами. Чисто теоретически, подобная информаия позволяет компилятору произвести дополнительные виды оптимизации. Теоретически, т.к. покрутив этот квалификатор и так и сяк я не сумел заставить компилятор хоть как-то изменить генерируемый код.
Основные варианты использования квалификатора restraint:

Continue reading

Тестовое задание.

В целом, я противник каких бы то нибыло тестовых заданий. Большинство компаний в качестве тестовых заданий дают либо совсем уж унылое говно, либо что-то, очень смахивающее на кусок необходимого им компонента. Да и вообще, надо очень сильно хотеть работать где-либо, чтоб согласиться тратить на это свое время.
Хотя, иногда, бывают и исключения. Например, это тестовое задание компании ESET. Делать я его не стал, но подход мне понравился. В качестве задания предлагается провести реверс-инжиниринг небольшого приложения, содержащего в себе простую (8 команд) виртуальную машину. Данная виртуальная машина используется для проверки правильности комбинации имя пользователя/пароль. На выходе должно быть написано приложение, использующее байт-код виртуальной машины и реализующее ее саму.
Для того чтобы кандидату было интереснее, в приложении присутствуют какие-то антиотладочные трюки, т.к. IDA ругается на сегмент экспорта, а Hex-Rays утверждает что SP некорректен.