macros mayores y menores definidas en sys / sysmacros.h introducidas por

Estoy escribiendo una clase que tiene una estructura similar a una matriz y quiero que una función miembro llamada minor sea la misma que la operación de matriz. Esto provoca algunos errores. Un caso de prueba mínimo en mi sistema:

#include  void minor(int row, int col); 

Cuando se comstack, clang proporciona el siguiente error:

 $ clang++ -Weverything -std=c++11 test.cpp test.cpp:2:21: error: too many arguments provided to function-like macro invocation void minor(int row, int col); ^ /usr/include/x86_64-linux-gnu/sys/sysmacros.h:67:10: note: macro 'minor' defined here # define minor(dev) gnu_dev_minor (dev) ^ test.cpp:2:6: error: variable has incomplete type 'void' void minor(int row, int col); ^ 2 errors generated. $ 

La parte relevante de sys / sysmacros.h es:

 /* Access the functions with their traditional names. */ # define major(dev) gnu_dev_major (dev) # define minor(dev) gnu_dev_minor (dev) # define makedev(maj, min) gnu_dev_makedev (maj, min) 

Claramente, estas macros específicas podrían ser # undef., Pero parece bastante tonto que las palabras de rutina como mayor y menor se definan como macros, particularmente al extraer parte de la biblioteca estándar de C ++. ¿Hay alguna razón para que estos sean definidos? ¿Es este un error en la biblioteca estándar que estoy usando? (libstdc ++ 4.8.2 como en las pruebas de Debian)

De acuerdo con el estándar de C ++, esos nombres no deben reservarse para la implementación y, por lo tanto, estar disponibles.

Según el man 3 makedev :

Las funciones makedev (), major () y minor () no se especifican en POSIX.1, pero están presentes en muchos otros sistemas

y

Estas interfaces se definen como macros. Desde glibc 2.3.3, han sido alias para tres funciones específicas de GNU: gnu_dev_makedev (), gnu_dev_major () y gnu_dev_minor (). Los últimos nombres se exportan, pero los nombres tradicionales son más portátiles.

Parece que no se eliminaron por compatibilidad con versiones anteriores (por ejemplo, https://bugzilla.redhat.com/show_bug.cgi?id=130601 ).

Creo que podrías #undef ellos sin grandes problemas (muchos proyectos proceden de esta manera).

Con G ++ / CLANG / MSVC también podrías hacer algo como:

 #pragma push_macro("minor") #undef minor // do what you need #pragma pop_macro("minor") 

Es feo, pero ayuda a nombrar conflictos.

Además, dependiendo de cómo esté estructurado su código, este truco puede ser útil:

 #define minor(dev) gnu_dev_major(dev) void (minor)(int row, int col) { /* ... */ } 

En la línea de definición de la función, el carácter después de ‘menor’ es un paréntesis cercano, por lo que no es una invocación de macro.