2010-12-01 14 views

Respuesta

4

Con las versiones recientes de clang, ahora es posible comprobar si existen intrínsecos incorporados utilizando la macro __has_builtin(), p. GCC esperanza

int popcount(int x) 
{ 
#if __has_builtin(__builtin_popcount) 
    return __builtin_popcount(x); 
#else 
    int count = 0; 
    for (; x != 0; x &= x - 1) 
    count++; 
    return count; 
#endif 
} 

Vamos también apoyará __has_builtin() en el futuro.

+0

¿Tiene alguna indicación de que este podría ser el caso? Por el momento, su solución simplemente bloquea el uso de gcc por parte de gcc. Supongo que durante al menos 5 años después de que se introdujera la función en gcc, aún se veían versiones que no la admitirían, algunas distribuciones son bastante lentas en la adaptación de las versiones más nuevas. –

+0

La macro __has_builtin() se ha mencionado en algunos hilos de la lista de distribución de GCC en enero de 2012 y este hilo http://comments.gmane.org/gmane.comp.gcc.help/42610 también es prometedor. Pero creo que es demasiado tarde para GCC 4.8, así que tendremos que esperar otro año. – Linoliumz

2

Los #ifdef comprueba si la Directiva __builtin_ctzll se define como una macro nombre , no le ayudará a determinar si existe una función__builtin_ctzll.

No estoy lo suficientemente familiarizado con gcc builtins para ayudarlo más que esto: ¿cómo podría faltar el intrínseco?

+0

No es compatible con una arquitectura particular, por ejemplo. – Charles

3

Lo único que debería funcionar de la caja es probar la versión de gcc y esperar que esto se haga consistentemente en todas las arquitecturas.

Esto no está garantizado, sin embargo, recientemente tuve un problema similar no con las funciones integradas pero con __thread para el almacenamiento local de subprocesos. Esto se implementa en algunas arquitecturas (Linux) pero no en otras (OS X, bsd?) Y no había forma de descubrir esto con una macro.

Si tiene GNU make puede hacer algo similar para detectar la existencia de una función particular en su Makefile:

__THREAD := $(shell echo '__thread int i;' | ${CC} ${CFLAGS} -xc -c -o /dev/null - 2> /dev/null || echo "NO") 
ifeq (${__THREAD},NO) 
${warning thread local storage (TLS) with '__thread' is not supported, switching to pthread_getkey} 
CFLAGS += -D__GNUC_NO_TLS__ 
endif 

Esto evita utilizar las utilidades de configuración más complejas.

Cuestiones relacionadas