【问题标题】:major and minor macros defined in sys/sysmacros.h pulled in by <iterator><iterator> 引入的 sys/sysmacros.h 中定义的主要和次要宏
【发布时间】:2014-04-10 01:29:30
【问题描述】:

我正在编写一个具有类似矩阵结构的类,并且我希望有一个名为 minor 的成员函数与矩阵运算相同。这会触发一些错误。我系统上的最小测试用例:

#include <iterator>
void minor(int row, int col);

编译时,clang 提供以下错误:

$ 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 的相关部分是:

/* 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,但将诸如major 和minor 之类的常规词定义为宏似乎很愚蠢,尤其是在引入C++ 标准库的一部分时。有什么理由需要定义这些吗?这是我正在使用的标准库中的错误吗? (Debian 测试中的 libstdc++ 4.8.2)

【问题讨论】:

  • 试试-std=c++11 -ansi
  • 添加 -ansi 可以使最小的测试用例工作,但它会在我的项目的其他地方触发错误,所以我不能启用它,至少在短期内是这样。除了 -ansi 还有其他选择吗?

标签: c++ macros glibc libstdc++


【解决方案1】:

根据 C++ 标准,这些名称不应保留给实现并因此可用。

根据man 3 makedev

makedev()、major() 和 minor() 函数未在 POSIX.1,但存在于许多其他系统上

这些接口被定义为宏。从 glibc 2.3.3 开始,它们 已成为三个 GNU 特定函数的别名: gnu_dev_makedev()、gnu_dev_major() 和 gnu_dev_minor()。后者 名称已导出,但传统名称更便于携带。

似乎它们并没有因为向后兼容性而被删除(例如https://bugzilla.redhat.com/show_bug.cgi?id=130601)。

我认为您可以#undef 它们而不会出现重大问题(许多项目都以这种方式进行)。

使用G++/CLANG/MSVC,您还可以执行以下操作:

#pragma push_macro("minor")
#undef minor

// do what you need

#pragma pop_macro("minor")

这很丑,但有助于解决命名冲突。

此外,根据您的代码结构,这个技巧可能很有用:

#define minor(dev) gnu_dev_major(dev)

void (minor)(int row, int col) { /* ... */ }

在函数定义行中,'minor'后面的字符是右括号,所以不是宏调用。

【讨论】:

  • 感谢指向 Redhat 错误的指针。我已经向 gcc 提交了一个错误,因为 -std=c++11 不应该引入这些宏。 Jonathan Wakely 将我的文件标记为 gcc.gnu.org/bugzilla/show_bug.cgi?id=51749 的骗子,并指出在 4.9 版本发布后,修复此问题是一般性问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
  • 2017-02-27
  • 2022-01-21
  • 1970-01-01
相关资源
最近更新 更多