Linux в Windows: x86_64-w64-mingw32-gcc не будет компилировать 64-разрядный исполняемый файл, как я могу решить эту проблему?

Я использую Debian 9 (стабильный), и недавно я решил установить mingw-w64, чтобы я мог заниматься кроссплатформенной разработкой на C / ++, поскольку у меня нет постоянного доступа к машине с Windows. Когда я впервые установил его пару дней назад, чтобы протестировать 32- и 64-битные сборки, казалось, что он работает, но теперь 64-битная команда (x86_64-w64-mingw32-gcc), кажется, выводит только 32-битные исполняемые файлы, несмотря на то, что она должна по умолчанию выставить только 64-битную. Я даже явно объявил параметры -m64 и -march=x86_64, пытаясь заставить его, но похоже, что независимо от того, что я пробую сейчас, он будет выполнять только 32-разрядную сборку.

Для справки, весь код состоит из трех файлов: hello.c, hellofunc.c и hellofunc.h. Файл hello.c просто вызывает функцию printHelloWorld, определенную в hellofunc.c:

void printHelloWorld(void){
    long z;

    printf("Hello World!\n");

    switch(sizeof(z)){
        case 4:
            printf("This program is 32-bit\n");
            break;
        case 8:
            printf("This program is 64-bit\n");
            break;
        default:
            printf("This program is of unknown bit size\n");
    }


    printf("Long int size is %i bytes long!\n", sizeof(z));
}

Ожидаемый результат - «Эта программа 32-разрядная» или 64-разрядная, с явным выражением, показывающим длину байта переменной типа long. Проблема, с которой я столкнулся, заключается в том, что, несмотря на то, что используется 64-разрядная команда mingw-w64 gcc, когда я тестирую ее в Windows, она отображает 32-разрядное сообщение и длину байта 4 вместо ожидаемых 8. .

Опять же, когда я изначально тестировал его сразу после загрузки, он работал, как ожидалось, и я понятия не имел, что могло изменить его функциональность по умолчанию за последние пару дней - я не устанавливал ничего нового, и все, что я делал, это пытался для работы с make-файлами (хотя в этом каталоге их нет). Кроме того, для записи, gcc по умолчанию, родной для моей системы Debian, отлично работает с командами -m32 и -m64, поэтому не похоже, что моя система не способна на это и ... на самом деле, во всяком случае, я ожидал бы такого поведения быть наоборот, поскольку Linux, похоже, требует специальной настройки для выполнения 32-битных сборок или запуска 32-битных программ на 64-битной машине.

В качестве последней попытки самостоятельно разобраться в проблеме я выполнил команду x86_64-w64-mingw32-gcc -v -o hello.exe hello.c hellofunc.c -I ., чтобы получить полную последовательность команд компилятора, а также запустил для нее gcc. Вот полный вывод, который я поместил на pastebin только для справки. Я не на 100% понимаю вывод, но серьезно похоже, что все настройки и параметры должны выводить 64-битные ?? Я не знаю, я все еще новичок в Linux и до сих пор не совсем понимаю, как анализировать, когда что-то идет не так, особенно когда что-то идет вразрез с явно определенной функциональностью lol.

Если бы кто-то мог порекомендовать возможные исправления для этого или альтернативы, о которых я, вероятно, не думал, я был бы очень признателен. Я пробовал поискать ответы в Google заранее, но x86_64-w64-ming32-gcc, кажется, только когда-либо заходит в разговор, чтобы сообщить новичкам, что это очевидный способ по умолчанию для компиляции для 64-битной архитектуры.

Спасибо за чтение и любую помощь, которую вы можете оказать, ура ~


person AniMerrill    schedule 13.06.2019    source источник
comment
В мире компиляторов Windows x86-64 (включая кросс-компиляторы MinGW) размер long составляет 32 бита, long long - 64 бита. Это отличается от целей x86-64, таких как Linux / MacOS и т. Д., С разными размерами типов. Список размеров компиляторов на базе Windows см. В этом документе MS: docs.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=vs-2019   -  person Michael Petch    schedule 13.06.2019
comment
@MichaelPetch Хм, это странно, но интересно. Значит, в разработке для Windows кажется, что большинство типов переменных имеют определенную длину в байтах? Есть ли способ протестировать архитектуру как меру работоспособности, аналогично тому, как этот пример работает в системах * nix?   -  person AniMerrill    schedule 13.06.2019
comment
У Agner Fog есть таблица с типом размеры для разных сред и компиляторов. Поскольку кросс-компиляторы x86-64 MinGW соответствуют размерам компилятора Microsoft для совместимости, вы можете просмотреть столбец 64-разрядная версия Microsoft, чтобы подтвердить это.   -  person Michael Petch    schedule 13.06.2019
comment
sizeof(void*) будет работать в большем количестве случаев, но даже это будет неправильным для ABI ILP32 (например, ABI ILP32 AArch64 и x86 -64 Linux x32 ABI)   -  person Peter Cordes    schedule 13.06.2019
comment
@PeterCordes: Этот вопрос состоит из двух частей. Я бы добавил stackoverflow.com / questions / 1505582 / как дубликат. У меня нет возможности самостоятельно добавить обман.   -  person Michael Petch    schedule 13.06.2019
comment
@MichaelPetch: Позволяет ли ТАК редактировать дублирующий список или для этого нужен золотой значок? Я думаю, что редактирование дублирующих списков появилось после того, как у меня были золотые значки во многих из вопросов, которые я вижу, поэтому я никогда не был уверен, была ли эта новая функция открыта для кого-либо после того, как вопрос был закрыт как дубликат.   -  person Peter Cordes    schedule 13.06.2019
comment
@PeterCordes Спасибо за эту информацию, похоже, это сработало с моей текущей схемой, но я буду иметь в виду, что это не совсем изощренное решение, которое, вероятно, будет работать везде. Я, вероятно, изучу решение, предложенное Майклом здесь, поскольку оно тоже кажется потенциально многообещающим. Извините всех за глупость, лол.   -  person AniMerrill    schedule 13.06.2019
comment
sizeof(void*) по-прежнему полезен, если ложноотрицательные результаты являются только проблемой производительности, а не правильностью. (например, чтобы выбрать более оптимальную версию, если доступны собственные 64-битные целые числа). В сочетании с некоторыми макросами CPP для определенных ABI ILP32-on-64, это охватывает реальные случаи. (Как 2_)   -  person Peter Cordes    schedule 13.06.2019
comment
@AniMerrill: В частности, я бы просмотрел этот ответ: stackoverflow.com/a/12338526/3857942   -  person Michael Petch    schedule 13.06.2019
comment
Также обратите внимание, что в C размер типа в битах sizeof(T) * CHAR_BIT. Вы можете просто распечатать это. sizeof(char) гарантированно будет 1, но CHAR_BIT не гарантированно будет 8, например. DSP с памятью с адресацией по словам может иметь 32-битные символы char / short / int, поэтому все они имеют sizeof () = 1.   -  person Peter Cordes    schedule 13.06.2019
comment
@MichaelPetch: да, это выглядит многообещающе, и я, вероятно, скину новую версию своего проекта hello world, просто чтобы поработать с этой опцией, так что у меня есть пример. Спасибо ~   -  person AniMerrill    schedule 13.06.2019
comment
кроме того, размер результата печати с %i равен UB. Вы должны использовать %zu   -  person phuclv    schedule 14.06.2019