Ответ 1
Поскольку вы отметили этот "gcc", попробуйте
#if __x86_64__
/* 64-bit */
#endif
есть макрос C или какой-то способ, которым я могу проверить, была ли моя c-программа скомпилирована как 64-битная или 32-битная во время компиляции в C?
Компилятор: GCC Операционные системы, которые мне нужны для проверки: Unix/Linux
Также как я могу проверить при запуске моей программы, если ОС способна на 64 бит?
Поскольку вы отметили этот "gcc", попробуйте
#if __x86_64__
/* 64-bit */
#endif
Вот правильный и переносимый тест, который не предполагает x86 или что-то еще:
#include <stdint.h>
#if UINTPTR_MAX == 0xffffffff
/* 32-bit */
#elif UINTPTR_MAX == 0xffffffffffffffff
/* 64-bit */
#else
/* wtf */
#endif
Легкий, который заставит адвоката языка защищаться.
if(sizeof (void *) * CHARBIT == 64) {
...
}
else {
...
}
Поскольку это постоянное выражение, оптимизирующий компилятор отбрасывает тест и помещает только правильный код в исполняемый файл.
Посмотрите следующий вопрос. В нем описывается использование директивы __LP__
gcc preprocessor
Использовать макрос для компилятора.
Я не знаю, на какую архитектуру вы нацеливаетесь, но поскольку вы не укажете ее, я буду считать, что вы запускаете машины Intel, поэтому, скорее всего, вас интересует тестирование для Intel x86 и AMD64.
Например:
#if defined(__i386__)
// IA-32
#elif defined(__x86_64__)
// AMD64
#else
# error Unsupported architecture
#endif
Однако я предпочитаю помещать их в отдельный заголовок и определять свой собственный макрос, не относящийся к компилятору.
Это зависит от вашей операционной системы/среды. Для Mac OS X см. как узнать, является ли текущая архитектура i386 или x86_64 в маках? (Xcode)
Тот же самый источник программы может (и должен быть способен) скомпилироваться в 64-разрядных компьютерах, 32-разрядных компьютерах, 36-разрядных компьютерах,...
Итак, просто взглянув на источник, если он хорош, вы не можете сказать, как он будет скомпилирован. Если источник не так хорош, возможно, можно догадаться, что предположил программист для его компиляции.
Мой ответ вам:
Существует способ проверить количество бит, необходимое для исходного файла только для плохих программ.
Вы должны стремиться к тому, чтобы ваши программы работали независимо от того, сколько бит они будут скомпилированы.
Посмотрите Предварительно определенные макросы компилятора C/С++, ссылку на макросы, предопределенные стандартами, компиляторами, библиотеками, операционными системами, и интерес к вашему вопросу, архитектуры.
GLIBC сам использует это (в inttypes.h
):
#if __WORDSIZE == 64
Используйте это значение 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;
}
Вопрос неоднозначен, поскольку он не указывает, является ли требование для 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-разрядной арифметики, поэтому они в основном бесполезны (по отношению к указанным атрибутам), за исключением контекст системы сборки, которая не является агностикой. Таким образом, для указанных атрибутов предпочтительно устанавливать макросы сборки, чтобы система сборки могла выбирать, какой вариант скомпилирован.