Ответы пользователя по тегу GCC
  • Тонкости Компиляторов. Почему в классах с++ не требуется объявление функции до вызова?

    @Mercury13
    Программист на «си с крестами» и не только
    Подозреваю, что объявление функции после вызова разрешили, потому что оно достаточно легко реализуемо, но даёт изрядную свободу прогеру. Например: несколько открытых конструкторов вызывают private init(), а этот init, как и все скрытые методы, сидит где-то в конце.

    Проходов компиляции может быть много — например, сначала мы говорим, что f(x) — это вызов, а вторым проходом определяем, с какой функцией f имеем дело. К тому же конкретно в Си++ любой код в теле класса — автоматический inline, то есть не создаёт кода, пока кто-то снаружи не вызовет.

    Умножение, приведение типа или ещё какая-то дрянь — это особенность метода разбора. Во многих языках, в том числе в Паскале, используется LL-разбор — сканирование слева направо, опознание слева направо. Ошибки наподобие «ожидалась точка с запятой» — это артефакт примитивных LL-анализаторов. В Си используется LR-разбор — сканирование слева направо, опознание справа налево, а ожидающие опознания лексемы хранятся в стеке.

    И вообще, если пишете собственный крайне специализированный язык, делайте его LL(1), это очень упростит разбор.

    Кстати, в Паскале принят обратный порядок видимости: private → protected → public → published. Последнее — поле доступно в рефлексии времени выполнения.
    Ответ написан
    Комментировать
  • Кроссплатформенное программирование на C?

    @Mercury13
    Программист на «си с крестами» и не только
    Что тогда делают? Есть три варианта.
    1. Перейти на кроссплатформенную библиотеку (Qt, например).
    2. Наладить свою небольшую библиотеку, которая когда-нибудь станет кроссплатформенной.
    3. Наладить механизм псевдонимов.
    Эти варианты можно объединять: что-то перевести на другую библиотеку, что-то написать своё.

    Примеры из личного кода.

    ОДИН. Ну, например, собственные механизмы работы с путями к файлам потихоньку уходят в сторону std::filesystem::path.

    ДВА. Ну, допустим, сделал свою библиотеку доступа к файлам — бонуса три. 1) Есть функции вроде writeIW (Intel word). 2) Проще писать свои абстрактные потоки, чем с std. 3) Феноменальная скорость под Windows (использует нечастый, но быстрый overlapped API с двойной буферизацией). На остальных ОС — обычная обёртка над FILE*.

    ТРИ. std::random_device из MinGW 9 давал детерминированную последовательность. Потом попытался бросить эту обходную ветку, но кто-то из программистов пожаловался — на его машине r_d просто не инициализировался.
    #if defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
    
        #define MINGW_RANDOM_DEVICE_WORKAROUND
    
        class MingwRandomDevice {};  // куча WinApi, опустим
    #else //defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
        #include <random>
        using MingwRandomDevice = std::random_device;
    #endif //defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__)
    Ответ написан
    1 комментарий
  • Как прочесть аргументы функции на стеке / заставить gcc хранить аргументы функции на стеке?

    @Mercury13
    Программист на «си с крестами» и не только
    https://godbolt.org/z/ARYhis
    Если посмотреть в пролог функции, она делает локальную копию нашей a. А желаемое место в стеке на 36 байтов выше, чем вы ищете.
    Разумеется, всё под x86. Вызов под x64 подразумевает регистры.

    UPD. А вот Интел не делает локальных копий и всё на месте.
    Ответ написан
    Комментировать
  • Какую оптимизацию отключить в g++ -O1, чтобы не было [optimized out]?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    -fno-tree-* (в общем, все, начинающиеся на tree и входящие в O1).
    Дальше выделять бессмысленно, каждая из них делает что-то маленькое.

    Но не включаем -fno-tree-copy-prop, оно выводит адову кучу ложных тревог.

    UPD. В настоящее время лучше использовать линкер LLD, и точка. Проект разросся, а линковка длится «целых» ДВЕ секунды.
    Ответ написан
    Комментировать
  • Как исправить ошибку при компиляции файла.c в MinGW?

    @Mercury13
    Программист на «си с крестами» и не только
    Вот и положите этот libmingwex-0.dll в каталог с программой. Всё в порядке, программа скомпилировалась, остаётся пустить.
    Если такое случается при запуске компилятора — что-то с компилятором, и переустановить надо ЕГО.
    (Покопался по интернету, завтра проверю на работе свежие версии MinGW)
    Ответ написан
    Комментировать
  • Где располагаются переменные в данном случае (стэк, куча)?

    @Mercury13
    Программист на «си с крестами» и не только
    Вы совершенно правы. Это массив из одного элемента, и при таком расположении он будет в стеке. Со всеми его полями: alloc, size и mp_d. При выходе из функции есть шансы, что он будет затёрт, и так действовать нельзя.

    Кто затрёт? Да кто угодно. Хоть драйвер, пожелавший воспользоваться твоим стеком. Хоть последующий вызов какой-нибудь функции.

    С другой стороны, на то и помечена структура __mpz_struct двумя подчерками, чтобы её не использовали.
    __mpz_struct* foo()
    {
        mpz_t var;
        return (__mpz_struct *)var;
    // C:\TestApps\RetLocal\main.cpp|15|warning: address of local variable 'var' returned [-Wreturn-local-addr]|
    }


    А так работает: всё в куче. Только не забывайте очищать через delete[].
    __mpz_struct* bar()
    {
        __mpz_struct* var = new mpz_t;
        return var;
    }
    Ответ написан
    2 комментария
  • Как правильно из zip архива считать текстовый файл с помощью PHYSFS?

    @Mercury13
    Программист на «си с крестами» и не только
    Нужно закрыть Си-строку.
    int length = PHYSFS_fileLength(myfile)
    myBuf = new char[length + 1];
    int length_read = PHYSFS_read(myfile, myBuf, 1, length);
    myBuf[length_read] = 0;
    Ответ написан
    Комментировать
  • Qt+QMake: как задать настройки компиляции для конкретного файла?

    @Mercury13 Автор вопроса
    Программист на «си с крестами» и не только
    И снова приходится отвечать самому.

    #pragma GCC optimize("O1")
    #pragma GCC optimize("no-lto")
    Ответ написан
    Комментировать
  • Зачем gcc просит подключить stdlib.h?

    @Mercury13
    Программист на «си с крестами» и не только
    Раз у вас stdlib.h закомментирован, вы, наверно, знаете, откуда malloc взялся. Попробуем раскрутить ошибки.

    note: include ‘ stdlib.h ’ or provide a declaration of ‘malloc’
    Компилятор, очевидно, знает, где этот malloc завалялся…

    warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
    …но неявно объявляет функцию.

    warning: incompatible implicit declaration of built-in function ‘malloc’
    Неявное определение int* malloc(int). Реальное void* malloc(size_t). Преобразовать (int*)malloc надо было.

    Почему всё-таки запустилось? А потому, что на целевой машине size_t = unsigned int, а размеры указателей совпадают практически всегда. После того, как функция неявно объявилась, линкер подцепил на её место стандартную, и соглашения вызова совпали.
    Ответ написан
    1 комментарий
  • Вопрос специалистам по GCC и темплейтам C++

    @Mercury13
    Программист на «си с крестами» и не только
    Всё, что я знаю: GCC — самый «въедливый» компилятор. После Intel и Embarcadero (про M$ не знаю) на «зашаблоненном» коде GCC найдёт ещё два десятка ошибок.
    Ответ написан
    Комментировать