c++ - 引用保留名称肯定是非法的吗?

标签 c++ c++11 language-lawyer c++14

std-proposals列表中,给出了以下代码:

#include <vector>
#include <algorithm>

void foo(const std::vector<int> &v) {
#ifndef _ALGORITHM
  std::for_each(v.begin(), v.end(), [](int i){std::cout << i; }
#endif
}

为了这个问题的目的,让我们忽略为什么给出该代码以及为什么以这种方式编写(因为有充分的理由,但在这里无关紧要)。它假设 _ALGORITHM是标准 header 内的 header 保护 <algorithm>与一些已知的标准库实现一起提供。这里没有可移植性的内在意图。

现在,_ALGORITHM当然是保留名称,每:

[C++11: 2.11/3]: In addition, some identifiers are reserved for use by C++ implementations and standard libraries (17.6.4.3.2) and shall not be used otherwise; no diagnostic is required.

[C++11: 17.6.4.3.2/1]: Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

我一直认为这段话的目的是防止程序员定义/变异/取消定义属于上述标准,以便标准库实现者可以使用这些名称而不必担心与客户端代码冲突。

但是,在 std-proposals 列表中,声称该代码本身是错误的,因为仅引用了这样的保留名称。我现在可以看到 [C++11: 2.11/3]: 中“不得以其他方式使用”这个短语的用法。可能确实暗示了这一点。

给出的一个实际理由是宏 _ALGORITHM例如,可以扩展到一些删除硬盘驱动器的代码。但是,考虑到该规则的可能意图,我想说这种可能性与 _ALGORITHM 明显的实现定义*性质有关。名称,与引用它完全非法的关系不大。

* 英语意义上的“实现定义”,而不是短语的 C++ 标准意义上的“实现定义”

我想说,只要我们很高兴我们将获得实现定义的结果,并且我们应该调查该宏对我们的实现意味着什么(如果它存在的话!),它不应该如果我们不尝试修改它,那么引用这样的宏本身就是非法的。

例如,到处都使用如下代码来区分编译为C的代码和编译为C++的代码:

#ifdef __cplusplus
extern "C" {
#endif

而且我从来没有听到过对此的提示。

那么,你怎么看? “不得以其他方式使用”是否包括简单地写这样一个名字?或者它可能不打算如此严格(这可能意味着调整标准措辞的机会)?

最佳答案

它是否合法是特定于实现的(和特定于标识符的)。

当标准授予实现使用这些名称的唯一权利时,包括使这些名称在用户代码中可用的权利。如果实现可以这样做,那就太好了。

但是如果一个实现没有明确赋予你权利,那么从“不得以其他方式使用”中可以清楚地看出标准没有,并且你有未定义的行为。

关于c++ - 引用保留名称肯定是非法的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29971760/

相关文章:

c++ - 带有通用格式说明符的 Printf

c++ - 如何抑制 C++ 中的个别警告?

c++ - 从逗号分隔的整数中解析 std::vector<int>

c++ - 从字符串中删除行注释

c++ - 通过用户定义的转换复制类类型的初始化

c++ - 无法在 std::chrono::time_point s 之间转换

c++ - gcc/ld : what is to -Wl, 动态链接中的-rpath 什么是静态链接中的-l 到-L?

C++ - 为什么不能使用 'const' 限定符创建静态成员函数

c++ - 不透明和匿名枚举声明如何符合标准要求?

c++ - std::vector<T> 是 `user-defined type` 吗?