在sys / sysmacros.h中定义的主要和次要宏,由< iterator> [英] major and minor macros defined in sys/sysmacros.h pulled in by <iterator>
问题描述
我正在写一个类,它有一个类矩阵结构,我想有一个成员函数,名为minor与矩阵操作相同。这会触发一些错误。在我的系统上的最小测试用例:
I'm writing a class that has a matrix-like structure and I want to have a member function named minor to be the same as the matrix operation. This triggers some errors. A minimal test case on my system:
#include <iterator>
void minor(int row, int col);
编译时,clang提供以下错误:
When compiled, clang provides the following 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.
$
sys / sysmacros.h的相关部分是:
The relevant portion of sys/sysmacros.h is:
/* 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)
显然,这些特定的宏可能是#undef'd,但似乎很愚蠢的例句和minor将被定义为宏,特别是在拉取部分C ++标准库时。是否有某些原因需要定义?这是我使用的标准库中的错误吗? (libstdc ++ 4.8.2在Debian测试中)
Clearly, these specific macros could be #undef'd, but it seems quite silly that such routine words as major and minor would be defined as macros, particularly when pulling in part of the C++ standard library. Is there some reason these need to be defined? Is this a bug in the standard library I'm using? (libstdc++ 4.8.2 as in Debian testing)
推荐答案
根据C ++标准,这些名称不应保留到实现
According to the C++ standard those names shouldn't be reserved to the implementation and thus be available.
根据 man 3 makedev
:
makedev(),major()和minor()函数没有在
POSIX.1中指定,但是存在于许多其他系统上
The makedev(), major(), and minor() functions are not specified in POSIX.1, but are present on many other systems
和
这些接口定义为宏。从glibc 2.3.3开始,它们
是三个GNU特定函数的别名:
gnu_dev_makedev(),gnu_dev_major()和gnu_dev_minor()。后面的
名称是导出的,但是传统名称更容易移植。
These interfaces are defined as macros. Since glibc 2.3.3, they have been aliases for three GNU-specific functions: gnu_dev_makedev(), gnu_dev_major(), and gnu_dev_minor(). The latter names are exported, but the traditional names are more portable.
看起来,向后兼容性(例如 https://bugzilla.redhat.com/show_bug.cgi?id=130601 ) 。
It seems that they aren't removed for backward compatibility (e.g. https://bugzilla.redhat.com/show_bug.cgi?id=130601).
我想你可以#undef没有重大问题(许多项目以这种方式进行)。
I think you could #undef them without major issues (many projects proceed in this way).
使用 G ++ / CLANG / MSVC 您也可以做类似的操作:
With G++/CLANG/MSVC you could also do something like:
#pragma push_macro("minor")
#undef minor
// do what you need
#pragma pop_macro("minor")
这很丑陋,但有助于命名冲突。
It's ugly, but helps with naming conflicts.
此外,根据代码的结构,这个技巧可能是有用的:
Moreover, depending on how your code is structured, this trick can be useful:
#define minor(dev) gnu_dev_major(dev)
void (minor)(int row, int col) { /* ... */ }
在函数定义行中,'minor'后的字符是一个右括号,因此它不是一个宏调用。
In the function definition line, the character after 'minor' is a close parenthesis, so it is not a macro invocation.
这篇关于在sys / sysmacros.h中定义的主要和次要宏,由< iterator>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!