Подтвердить что ты не робот

Обнаружение 64-битной компиляции в C

есть макрос C или какой-то способ, которым я могу проверить, была ли моя c-программа скомпилирована как 64-битная или 32-битная во время компиляции в C?

Компилятор: GCC Операционные системы, которые мне нужны для проверки: Unix/Linux

Также как я могу проверить при запуске моей программы, если ОС способна на 64 бит?

4b9b3361

Ответ 1

Поскольку вы отметили этот "gcc", попробуйте

#if __x86_64__
/* 64-bit */
#endif

Ответ 2

Вот правильный и переносимый тест, который не предполагает x86 или что-то еще:

#include <stdint.h>
#if UINTPTR_MAX == 0xffffffff
/* 32-bit */
#elif UINTPTR_MAX == 0xffffffffffffffff
/* 64-bit */
#else
/* wtf */
#endif

Ответ 3

Легкий, который заставит адвоката языка защищаться.

if(sizeof (void *) * CHARBIT == 64) {
...
}
else {
...
}

Поскольку это постоянное выражение, оптимизирующий компилятор отбрасывает тест и помещает только правильный код в исполняемый файл.

Ответ 4

Посмотрите следующий вопрос. В нем описывается использование директивы __LP__ gcc preprocessor

Ответ 5

Использовать макрос для компилятора.

Я не знаю, на какую архитектуру вы нацеливаетесь, но поскольку вы не укажете ее, я буду считать, что вы запускаете машины Intel, поэтому, скорее всего, вас интересует тестирование для Intel x86 и AMD64.

Например:

#if defined(__i386__)
// IA-32
#elif defined(__x86_64__)
// AMD64
#else
# error Unsupported architecture
#endif

Однако я предпочитаю помещать их в отдельный заголовок и определять свой собственный макрос, не относящийся к компилятору.

Ответ 7

Тот же самый источник программы может (и должен быть способен) скомпилироваться в 64-разрядных компьютерах, 32-разрядных компьютерах, 36-разрядных компьютерах,...

Итак, просто взглянув на источник, если он хорош, вы не можете сказать, как он будет скомпилирован. Если источник не так хорош, возможно, можно догадаться, что предположил программист для его компиляции.

Мой ответ вам:

Существует способ проверить количество бит, необходимое для исходного файла только для плохих программ.

Вы должны стремиться к тому, чтобы ваши программы работали независимо от того, сколько бит они будут скомпилированы.

Ответ 9

GLIBC сам использует это (в inttypes.h):

#if __WORDSIZE == 64

Ответ 10

Используйте это значение UINTPTR_MAX, чтобы проверить тип сборки.

#include <stdio.h>
#include <limits.h>

#if UINTPTR_MAX == 0xffffffffffffffffULL               
# define BUILD_64   1
#endif

int main(void) {

    #ifdef BUILD_64
    printf("Your Build is 64-bit\n");

    #else
    printf("Your Build is 32-bit\n");

    #endif
    return 0;
}

Ответ 11

Вопрос неоднозначен, поскольку он не указывает, является ли требование для 64-разрядных указателей или 64-разрядной собственной целочисленной арифметикой или и то, и другое.

В некоторых других ответах указано, как обнаружить 64-битные указатели. Несмотря на то, что вопрос буквально оговаривает "скомпилированный как", обратите внимание, что это не гарантирует наличия 64-разрядного адресного пространства.

Для многих систем обнаружение 64-битных указателей эквивалентно обнаружению того, что 64-разрядная арифметика не эмулируется, но это не гарантируется для всех потенциальных сценариев. Например, хотя Emscripten эмулирует память с использованием массивов Javascript, которые имеют максимальный размер 2 32 -1, чтобы обеспечить совместимость для компиляции C/С++ код таргетинга 64-битный, я считаю, что Emscripten агностик о границах (хотя я этого не тестировал). Принимая во внимание, что независимо от ограничений, установленных компилятором, Emscripten always использует 32-разрядную арифметику. Таким образом, кажется, что Emscripten будет принимать байт-код LLVM, предназначенный для 64-разрядных int и 64-битных указателей, и эмулировать их в лучшем случае возможности Javascript.

Я изначально предлагал обнаруживать 64-битные "родные" целые числа следующим образом, но, как отметил Патрик Шлютер, это обнаруживает только редкий случай ILP64:

#include <stdint.h>
#if UINT_MAX >= 0xffffffffffffffff
// 64-bit "native" integers
#endif

Таким образом, правильный ответ заключается в том, что, как правило, вы не должны делать каких-либо предположений об адресном пространстве или арифметической эффективности туманной "64-разрядной" классификации, основанной на значениях пределов отчетов компилятора. Ваш компилятор может поддерживать непереносные флаги препроцессора для конкретной модели данных или микропроцессорной архитектуры, но с учетом целевых задач GCC и сценария Emscripten (в котором Clang эмулирует GCC) даже они могут вводить в заблуждение (хотя я его не тестировал).

В целом ни один из этих сценариев не может быть использован для предоставления надежного указания на наличие 64-разрядного адресного пространства и неэмулируемой 64-разрядной арифметики, поэтому они в основном бесполезны (по отношению к указанным атрибутам), за исключением контекст системы сборки, которая не является агностикой. Таким образом, для указанных атрибутов предпочтительно устанавливать макросы сборки, чтобы система сборки могла выбирать, какой вариант скомпилирован.