c++ macros glibc libstdc++

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.