macros majeures et mineures définies dans sys / sysmacros.h tirées par

J’écris une classe qui a une structure de type masortingce et je souhaite qu’une fonction membre nommée mineur soit identique à l’opération de masortingce. Cela déclenche des erreurs. Un cas de test minimal sur mon système:

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

Une fois compilé, clang fournit l’erreur suivante:

 $ 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 partie pertinente de sys / sysmacros.h est:

 /* 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) 

Il est clair que ces macros spécifiques pourraient être # non définies, mais il semble assez ridicule que des mots de routine comme majeurs et mineurs soient définis comme des macros, en particulier lors de l’extraction d’une partie de la bibliothèque standard C ++. Y a-t-il une raison pour les définir? Est-ce un bug dans la bibliothèque standard que j’utilise? (libstdc ++ 4.8.2 comme dans les tests Debian)

Selon la norme C ++, ces noms ne devraient pas être réservés à l’implémentation et donc être disponibles.

Selon l’ man 3 makedev :

Les fonctions makedev (), major () et minor () ne sont pas spécifiées dans POSIX.1, mais sont présentes sur de nombreux autres systèmes.

et

Ces interfaces sont définies comme des macros. Depuis la glibc 2.3.3, ils sont des alias pour trois fonctions spécifiques à GNU: gnu_dev_makedev (), gnu_dev_major () et gnu_dev_minor (). Les derniers noms sont exportés, mais les noms traditionnels sont plus portables.

Il semble qu’ils ne soient pas supprimés pour des raisons de compatibilité ascendante (par exemple, https://bugzilla.redhat.com/show_bug.cgi?id=130601 ).

Je pense que vous pourriez # les définir sans problèmes majeurs (beaucoup de projets se déroulent de cette façon).

Avec G ++ / CLANG / MSVC, vous pouvez également faire quelque chose comme:

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

C’est moche, mais ça aide à nommer les conflits.

De plus, en fonction de la structure de votre code, cette astuce peut être utile:

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

Dans la ligne de définition de la fonction, le caractère après «mineur» est une parenthèse proche, il ne s’agit donc pas d’une macro invocation.