Казалось бы, что сложного? Написал вот такой код:
// Определяем имя компьютера
char computerName[200]={0};
DWORD dummy = sizeof(computerName)/sizeof(char);
GetComputerNameA(computerName, &dummy);
computer = QString::fromLocal8Bit(computerName);
// Определяем текущий каталог
char currentDir[400]={0};
GetCurrentDirectoryA(sizeof(currentDir)/sizeof(char), currentDir);
curdir = QString::fromLocal8Bit(currentDir);
Всё хорошо, всё компилируется... и ничего не показывает. В соответствующих строках - пусто.
Перечитываю код - вроде всё верно, должно работать. Значит начинаем отладку.
Отладка, как обычно, начинается с полной пересборки проекта. Rebuild - это просто обязательное действие. Оно гарантирует что мы не будем искать ошибку в неправильном коде, который слинковался в результате ошибки компоновки с приращением
(incremental linking) или неправильно разрешенными зависимостями между файлами.
Конечно же пересборка проблему не устранила. Попытка пройтись по шагам в построчном отладчике тоже ничего не дала - проект собран в release, код перемешан и указатель прыгает как бешенный по каждому F10 (Step over).
Зато просмотр окна disassemble (Alt+8) выявил, что функции наши не вызываются вовсе. Как будто и нет этого кода...
И действительно, получившийся EXE не зависит от функций GetComputerNameA , GetCurrentDirectoryA и прочих.
Чтобы убедиться что в эту ветку кода вообще заходит управление, добавил перед вышеприведённым кодом
искусственный бряк:
__asm int 3;
Эта инструкция предназначена для останова в отладчике.
Проект успешно брякнулся, значит код в этой ветке исполняется. Тут моё подозрение пало на компоновщик, и я некоторое время изучал его опции. Всё было верно.
Круг подозреваемых всё более сужался. Было ясно, что что-то происходит при компиляции. Первая мысль была про неверную оптимизацию,
но я её сразу отбросил.
Подумав некоторое время, я стёр строку комментария "// Определяем имя компьютера".
На моё счастье я забыл описать переменную computer выше и получил ошибку.
Но чудо: ошибка указывала на строку с другим номером!
После этого стало всё ясно:
- файл изначально писался под linux-ом и переводы строк были обычные для unix-систем (\n).
- эту часть файла я дописывал под windows, вставив из другого файла (\r\n).
- компилятор запутался в разных переводах строк и не посчитал за перевод строки символы после комментария. Таким образом, следующие строки считались продолжением однострочного комментария...
Проблема решилась в меню File->Advanced Save Options указанием Line Endings и сохранением файла.
Мораль:
- переводы строк тоже имеют значение и могут запутать компилятор.
- Умение пользоваться инструментарием вроде Dependency Walker или встроенного дисассемблера MSVS сильно ускоряет локализацию проблемы.
Теперь принудительная установка окончаний строк наряду с указанием кодировки в моём обязательном списке того, что надо сделать при таких необычных проблемах с компиляцией.
Комментариев нет:
Отправить комментарий