Какую директиву препроцессора или другой метод я должен использовать, чтобы различить 32- и 64-битную среду? - PullRequest
0 голосов
/ 15 мая 2009

Я хотел бы скомпилировать следующую C программу для 32- и 64-битных систем.

#include <stdio.h>                                                                                                                                                                  
#include <stdlib.h>                                                                                                                                                                 
#include <stddef.h>                                                                                                                                                                 

int main(int argc, char** argv) {
  size_t size = atoi(argv[1]);                                                                                                                                                      
  int *array;                                                                                                                                                                       

  array = malloc(size * sizeof(int));                                                                                                                                               
  if (array == NULL) {                                                                                                                                                              
    fprintf(stderr, "could not allocate memory\n");                                                                                                                                 
    exit(1);                                                                                                                                                                        
  }                                                                                                                                                                                  
  fprintf(stdout, "memory allocated on heap: %u bytes\n", sizeof(int)*size);                                                                                                        

  fprintf(stdout, "press Return to quit\n");                                                                                                                                        
  getchar();                                                                                                                                                                        

  fprintf(stdout, "freeing memory\n");                                                                                                                                              
  free(array);                                                                                                                                                                      

  exit(0);                                                                                                                                                                          
}         

То, что я делал с Makefile, - это передача -m32 и -64 для создания двоичных файлов:

CFLAGS=-ansi -pedantic -Wall -O3
32BIT_ARCH=-m32
64BIT_ARCH=-m64
32_CFLAGS=${32BIT_ARCH} ${CFLAGS}
64_CFLAGS=${64BIT_ARCH} ${CFLAGS}
CC=gcc
ARRAY_32BIT_BINARY_NAME=arrayTest32
ARRAY_64BIT_BINARY_NAME=arrayTest64

all: ${ARRAY_32BIT_BINARY_NAME} ${ARRAY_64BIT_BINARY_NAME}
arrayTest32: main32_array.o 
             ${CC} ${32_CFLAGS} main32_array.o -o ${ARRAY_32BIT_BINARY_NAME}
arrayTest64: main64_array.o
             ${CC} ${64_CFLAGS} main64_array.o -o ${ARRAY_64BIT_BINARY_NAME}
main32_array.o: main.c
             ${CC} ${32_CFLAGS} -c main.c -o main32_array.o 
main64_array.o: main.c
             ${CC} ${64_CFLAGS} -c main.c -o main64_array.o 
clean:
             -rm *.o *~ ${ARRAY_32BIT_BINARY_NAME} ${ARRAY_64BIT_BINARY_NAME}
install:
             cp ${ARRAY_32BIT_BINARY_NAME} ${ARRAY_64BIT_BINARY_NAME} ../bin

Это прекрасно работает, но я сталкиваюсь с предупреждением при компиляции:

$ make                                                                                                                                   
gcc -m32 -ansi -pedantic -Wall -O3 -c main.c -o main32_array.o                                                                                                                      
gcc -m32 -ansi -pedantic -Wall -O3 main32_array.o -o arrayTest32                                                                                                                    
gcc -m64 -ansi -pedantic -Wall -O3 -c main.c -o main64_array.o                                                                                                                      
main.c: In function ‘main’:                                                                                                                                                         
main.c:14: warning: format ‘%u’ expects type ‘unsigned int’, but argument 3 has type ‘long unsigned int’                                                                            
gcc -m64 -ansi -pedantic -Wall -O3 main64_array.o -o arrayTest64  

Я хотел бы исправить это предупреждение, не имея двух файлов main.c для двух «битовых» целей.

Есть ли #ifndef или другое условное препроцессор, которое я могу добавить к строке 14 main.c для обработки этой разницы?

Или есть другой и лучший способ справиться с этим?

РЕДАКТИРОВАТЬ : я использовал следующее решение:

#if defined(__LP64__)                                                                                                                                                               
  fprintf(stdout, "memory allocated on heap: %lu bytes\n", sizeof(int)*size);                                                                                                       
#else                                                                                                                                                                               
  fprintf(stdout, "memory allocated on heap: %u bytes\n", sizeof(int)*size);                                                                                                        
#endif      

Ответы [ 5 ]

4 голосов
/ 15 мая 2009

C99 предоставляет модификатор 'z' для печати значений size_t; используйте это в строке формата.

2 голосов
/ 15 мая 2009

См. здесь для аналогичного вопроса.

LP64 _LP64 Эти макросы определены со значением 1, если (и только если) сборник для цели, где долго int и pointer используют как 64-битные, так и int использует 32-битный.

0 голосов
/ 16 мая 2009

Принятый ответ приемлем, если вам нужно переноситься на компиляторы не-C99 (например, Visual Studio), но, поскольку вы, похоже, используете только gcc, я настоятельно рекомендую #define __STDC_FORMAT_MACROS и использовать PRI * макросы, как я описал здесь . Тогда вам не нужно будет сбрасывать ваш код ненужными #ifdefs каждый раз, когда вам нужно вывести 64-битное целое число.

0 голосов
/ 15 мая 2009

Вы не хотите иметь #ifdef для каждой строки кода, которая может отличаться, как эта - она ​​не будет масштабироваться.

Проблема в том, что sizeof () возвращает 64-битное количество на 64-битном. Одно из возможных исправлений:

fprintf (стандартный вывод, «память, выделенная в куче:% u байтов \ n», (беззнаковое целое) (sizeof (int) * размер));

При условии, что вы знаете, что количество всегда будет 32-разрядным.

...