c++ - macros mayores y menores definidas en sys/sysmacros.h introducidas por<iterator>
glibc libstdc++ (1)
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 <iterator>
void minor(int row, int col);
Cuando se compila, 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 cuando se extraen de una 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 han eliminado por compatibilidad con versiones anteriores (p. Ej., 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 puedes 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.