将函数声明为静态,然后声明为非静态:这是标准的吗?
我注意到一种非常奇怪的行为,如果是标准的,我会很乐意利用它(我想用它做的事情解释起来相当复杂,并且与问题无关)。
行为是:
static void name();
void name() {
/* This function is now static, even if in the declaration
* there is no static keyword. Tested on GCC and VS. */
}
奇怪的是,逆运算会产生编译时错误:
void name();
static void name() {
/* Illegal */
}
那么,这是标准吗?我可以期望其他编译器也有相同的行为吗?谢谢!
I noticed a very curious behavior that, if standard, I would be very happy to exploit (what I'd like to do with it is fairly complex to explain and irrelevant to the question).
The behavior is:
static void name();
void name() {
/* This function is now static, even if in the declaration
* there is no static keyword. Tested on GCC and VS. */
}
What's curious is that the inverse produces a compile time error:
void name();
static void name() {
/* Illegal */
}
So, is this standard and can I expect other compilers to behave the same way? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
C++标准:
在第一种情况下,
name
是在命名空间范围(特别是全局命名空间)中声明的。因此,第一个声明会更改第二个声明的链接 逆向声明被禁止,因为:
因此,在您的第二个示例中,第一个声明具有外部链接(通过 7.1.1/6),第二个声明具有内部链接(明确),并且这些声明不同意。
还询问了 C,并且我想这是同样的事情,但我这里有一本 C++ 书,而你可以像我一样在线查找 C 标准草案;-)
C++ standard:
In your first case,
name
is declared in a namespace scope (specifically, the global namespace). The first declaration therefore alters the linkage of the second declaration.The inverse is banned because:
So, in your second example, the first declaration has external linkage (by 7.1.1/6), and the second has internal linkage (explicitly), and these do not agree.
You also ask about C, and I imagine it's the same sort of thing. But I have the C++ book right here, whereas you're as capable of looking in a draft C standard online as I am ;-)
声明函数时,将自动使用您在函数原型上放置的(或隐含的)限定符。
因此,在第二种情况下,原型上缺少
static
意味着该函数被定义为非静态,然后当它后来被声明为静态时,这是一个错误。如果您在原型中省略返回类型,则默认值为
int
,然后您将再次收到void
返回类型的错误。同样的情况也发生在__crtapi
和__stdcall
以及__declspec()
(在 Microsoft C 编译器中)。Qualifiers that you put on the function prototype (or that are implied) are automatically used when the function is declared.
So in your second case the lack of
static
on the prototype meant that the function was defined as NOT static, and then when it was later declared as static, that was an error.If you were to leave off the return type in the prototype, then the default would be
int
and then you would get an error again with thevoid
return type. The same thing happens with__crtapi
and__stdcall
and__declspec()
(in the Microsoft C compiler).