【问题标题】:Are extern extern "C", and extern "C" extern, allowed?是否允许 extern extern "C" 和 extern "C" extern?
【发布时间】:2019-12-22 09:20:17
【问题描述】:

这段代码正确吗?

extern "C" extern int x;       // 1
extern extern "C" int y;       // 2
extern "C" extern "C" int z;   // 3

int main() { }

gcc 将 1 和 2 视为语法错误拒绝并接受 3。clang 接受所有这三个但对它们都给出重复声明说明符警告。

也许相关的是 C++17 [dcl.stc]/5:

extern 说明符只能应用于变量和函数的名称。 extern 说明符不能用于类成员或函数参数的声明。对于声明的名称的链接 带有extern 说明符,参见 6.5。 [注意:extern 关键字也可以用在 explicit-instantiations 和 linkage-specifications 中,但 它不是 storage-类说明符 在这种情况下。 — 尾注]

【问题讨论】:

  • 你为什么觉得你想写这样的代码?
  • @LightnessRacesinOrbit 这有什么关系?
  • *叹气* 好吧,没关系。
  • 这是我确信我即将学习一些值得学习的东西的问题之一,但我不太确定是什么。我能找到与之相关的唯一注意事项是,在将非系统标头 #include 包装到 extern "C" 之前,您应该验证标头尚未包含链接规范——这意味着执行两次是不需要的。
  • 你看过this的视频吗?

标签: c++ language-lawyer extern extern-c


【解决方案1】:

extern extern "C" 不是有效语法,因为extern "C" 不是说明符,因此不能出现在 decl-specifier-seq 中。相反,extern "C" 只能作为 linkage-specification 的一部分出现,其语法为

extern string-literal { declaration-seq(opt) }
extern string-literal 声明

因此,extern "C" 必须首先出现。

另外,根据 [dcl.link]/7,extern "C" extern 也无效:

直接包含在 linkage-specification 中的声明被视为包含 extern 说明符 (10.1.1),以便确定声明名称的链接以及它是否是一个定义。这样的声明不应指定存储类。

extern 是存储类说明符。)

不过,似乎没有任何规则禁止extern "C" extern "C"

【讨论】:

    猜你喜欢
    • 2016-11-03
    • 2011-11-09
    • 2015-03-18
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    相关资源
    最近更新 更多