C++中函数声明的其他类型违反了类型安全吗?

7

我是C++的新手,正在尝试一些东西。我遇到了以下代码:

#include<iostream>  

void t(){
    std::cout << "func t()" << std::endl;
}

int main(int argc, char **argv) {
    int t(); //declaration of function
    std::cout << t() << std::endl;
}

输出结果为"func t()\n6295712"。我关注的是t()函数打印的随机(?)数字。
我的问题是:为什么可以声明返回类型不同的函数(这里是int而不是void),而没有任何错误?这不是违反类型安全性的行为吗,因为我从未定义过返回类型为“int”的函数?
使用的编译器:gcc(Ubuntu 4.8.4-2ubuntu1~14.04.1)4.8.4

我的输出结果是 func t()\n6295680,这与仅有的 6295712 不同。你的程序真的只打印了那个数字吗? - Marcus Müller
你说得对,我已经编辑了 - 我只关注了数字,忘记了其他的输出。谢谢。 - no_use123
可以确认这是真的 http://coliru.stacked-crooked.com/a/f9b957636b731736 - Lightness Races in Orbit
1
我认为这是gcc的一个bug,clang无法编译它。正在寻找标准的正确部分... - Barry
我同意Barry(哈哈)。大致浏览了一下标准,这个不是一个可行的重载,而且函数声明在参数列表和返回类型上也不一致。我无法看出这个程序是合法的。可以说这是未定义行为而不是非法的,但我仍然希望主流编译器能够提供诊断信息。 - Lightness Races in Orbit
@BarryTheHatchet 最好的我能找到的是一条注释。 - Barry
1个回答

4
我能找到的唯一相关信息是在 [basic.scope.pdecl] 中的一条注释:

块作用域中的函数声明和带有 extern 说明符的变量声明是指向封闭命名空间成员的声明,但它们不会引入新名称到该作用域中。

所以当你写:

void t();

int main() {
    int t();  // *
}

这个内部声明是指外层命名空间的成员。因此,它相当于编写:

void t();
int t();

int main() {}

但是函数不能仅在返回类型上进行重载,因此这段代码是不合法的。Clang拒绝这两个程序,gcc只拒绝后一个。我认为这是一个gcc的错误。

1
谢谢您的回答。我已经向GCC Bugzilla https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70414提交了一个错误报告。如果这个问题得到确认,我会接受您的答案。 - no_use123
s/override/overload/ - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接