C++ 异常规范在声明和实现功能时不兼容

C++ 异常规范在声明和实现功能时不兼容,c++,c++11,g++,clang++,C++,C++11,G++,Clang++,我们有以下代码 int main() { void f() throw(int); f(); return 0; } void f() { } GCC和clang编译得很好。但是,在标准中有这样一段: n3376 15.4/4 如果函数的任何声明有一个异常规范,该规范不是noexcept规范 所有异常,该函数的所有声明,包括定义和任何显式专门化,都应具有兼容的异常规范 例如:gcc-error,clang-warning void f() throw(int); int ma

我们有以下代码

int main()
{
  void f() throw(int);
  f();
  return 0;
}

void f() { }
GCC和clang编译得很好。但是,在标准中有这样一段:

n3376 15.4/4

如果函数的任何声明有一个异常规范,该规范不是noexcept规范 所有异常,该函数的所有声明,包括定义和任何显式专门化,都应具有兼容的异常规范

例如:gcc-error,clang-warning

void f() throw(int);

int main()
{
  f();
  return 0;
}

void f() { }

为什么这些片段有区别?谢谢。

std中的n3376 15.4/4规定,函数的所有声明和定义必须具有相同的抛出类型。在这里:

void f() throw(int);
int main()
{
  f();
  return 0;
}

void f() { }
声明
void f()抛出(int)
和定义
void f(){}
在全局scop中。所以它们是冲突的,因为声明是针对抛出int的函数的,而定义是针对没有抛出规范的函数的

现在,当您将声明放在主scop中时,定义不在同一scop中,在这个scop中,定义是未知的,因此您可以编译


我希望您理解我的英语,很抱歉。

在另一个函数中声明的函数是否在外部引用了同名函数的定义?在另一个函数中声明函数意味着什么?是的,但问题(即使是编译器问题)与此相关,而与异常规范的处理无关。例如,如果将
f
声明为在
main
内部返回
int
,但在
main
外部返回
void
,它仍会编译。即使您调用
f
并使用其声称的返回值。至少在g++和叮当声中:有趣的是,英特尔编译器发出了警告。@jogojapan,接受。奇怪的行为,gcc bugtracker中有这样的东西吗?有参数-Wmissing声明,在这种情况下会发出警告…我能找到的最接近的是:但这只是关于您可以在其他函数中声明函数的事实。它不包括声明和定义之间可能存在的不一致。嗯。。。在块范围内有PAR 3.3.2/10函数声明,在块作用域中使用ExtExn说明符的变量声明指的是封闭命名空间的成员声明,但它们不向该范围引入新名称。我认为这是相关的。不是真的,但被接受了。实际上,clang现在可以处理此情况,但仅限于警告: