我们可以在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限定符。感谢标准引用!