我们可以在main的参数中添加CV限定符吗? P>我所知,在C或C++中, main < /Cal>的签名应该是 int main(空隙)< /C>( Value/Cuth>在C++中是可选的)或 int main(int,char **)。但是,以下代码在gcc/g++/clang/clang++中编译时没有警告(-Wall-Wextra-Wpedantic) int main(int, const char * const * const argv){}
我们可以在main的参数中添加CV限定符吗? P>我所知,在C或C++中, main < /Cal>的签名应该是 int main(空隙)< /C>( Value/Cuth>在C++中是可选的)或 int main(int,char **)。但是,以下代码在gcc/g++/clang/clang++中编译时没有警告(-Wall-Wextra-Wpedantic) int main(int, const char * const * const argv){},c++,c,gcc,clang,language-lawyer,C++,C,Gcc,Clang,Language Lawyer,上面的代码合法吗?换句话说,我们是否可以在main的参数中添加CV限定符,或者这只是编译器的一个扩展,不需要诊断?标准C++11允许实现接受它喜欢的任何签名,它只要求有问题的两个签名。它还必须具有返回类型int 3.6.1主功能[basic.start.Main] 2实现不应预定义主要功能。此功能不应过载。它应具有int类型的返回类型,但其类型由实现定义。所有实施应: 允许以下两种定义的main: int main() { /* ... */ } 及 int main(int argc, ch
上面的代码合法吗?换句话说,我们是否可以在
main
的参数中添加CV限定符,或者这只是编译器的一个扩展,不需要诊断?标准C++11
允许实现接受它喜欢的任何签名,它只要求有问题的两个签名。它还必须具有返回类型int
3.6.1主功能[basic.start.Main]
2实现不应预定义主要功能。此功能不应过载。它应具有int类型的返回类型,但其类型由实现定义。所有实施应:
允许以下两种定义的main:
int main() { /* ...
*/ }
及
int main(int argc, char* argv[]) { /* ...
*/ }
因此,为了解决主要问题:
我们可以在main的参数中添加CV限定符吗?
如果实现支持它,我们可以这样做,但是如果我们支持,那么代码就不太可能是可移植的
只有将cv限定符(最多)添加到参数变量本身,而不是其指向的类型时,代码才能完全可移植:
// still portable, same signature as int main(int, char**)
int main(int, char** const argv);
// not portable
int main(int, char* const* argv);
// not portable
int main(int, const char** argv);
记住C和C++是两种截然不同的语言。两人的答案几乎相同,但也值得一提,尤其是考虑到律师的语言标签。链接到C11的N1570草稿 第5.1.2.2.1节介绍了托管实施的
main
定义:
程序启动时调用的函数名为main
。这个
实现没有声明此函数的原型。应该是
使用返回类型int
定义且不带参数:
intmain(void){/*…*/}
或具有两个参数(此处称为argc
和argv
,
尽管可以使用任何名称,因为它们是中函数的本地名称
声明如下:
intmain(intargc,char*argv[]){/*…*/}
或同等品;或者以其他实现定义的方式
添加了const
或volatile
限定符的定义不等同于所示的表单,因此实现没有义务接受它。但由于该部分不是约束,所以实现也不需要抱怨它。特别是,如果一个实现记录了它接受const
和/或volatile
限定符,那么它们对该实现完全有效
(实际上,大多数编译器可能不会抱怨。)
请注意,这仅适用于托管实现。对于独立实现(通常用于没有操作系统的嵌入式目标):
。。。在程序中调用的函数的名称和类型
启动是由实现定义的
(5.1.2.1第1段),这意味着独立实现的主功能没有可移植的定义(它甚至不需要被称为
main
)。@STF我明白了,但是您有一些标准参考吗?据我记忆所及(我现在还没有这个标准),签名被授权为intmain()
或intmain(int,char**)
,或者,语法糖,intmain(int,char*[])
@Galik为什么?指针不是隐式可转换的,它不是标准的数组到指针衰减。所以简历资格应该是签名的一部分。也许我遗漏了什么。最后一个const
没有问题,因为它不改变函数类型,因为它是顶级的。前两个const
s不正常。注意:对于正式的学究式实现,托管实现和独立实现之间存在差异。@Cheersandhth.-Alf这也是我的想法,顶层被忽略,但其余的不应该被忽略。@vsoftco你是对的,它确实更改了签名,soz:)这是完全正确的,因为函数的签名不包括返回类型(对于main
,它必须是int
)@cheers-sandhth.-Alf你是说,如果不是这样的话,它的类型是实现定义的,是指返回类型吗?函数的类型包括返回类型。签名是链接器认为的:“名称、参数类型列表(8.3.5)和封闭的命名空间(如果有的话)”(来自C++14§1.3.17)。§3.6.1讨论了不带返回类型的函数类型。@Cheersandhth.-Alf谢谢!我认为这个答案会更好(:),如果包括讨论可以为完全可移植的代码添加哪些CV限定符。感谢标准引用!