C和C++之间的什么区别阻止了这个折衷的代码示例在C++中编译?

ztmd8pv5  于 2022-11-27  发布在  其他
关注(0)|答案(3)|浏览(229)

我只是想知道问题 'Hello, World!' in C without semicolons and without 'if', 'while', or 'for' statements 的内容。
以下代码在C中可以工作,但在C++中不能:

int main(int argc, char *argv[printf("Hello, World!\n")]) {}

在C++中,我得到了这个错误:

error: expected ‘,’ or ‘...’ before ‘argv’|
warning: second argument of ‘int main(int, char*)’ should be ‘char **’ [-Wmain]|
||=== Build finished: 1 errors, 1 warnings ===|

为什么它在C++中不起作用?

vq8itlhq

vq8itlhq1#

因为C++没有任何variable-length array特性。
中的argv参数
char *argv[printf("Hello, World!\n")]
是可变长度数组。
指定数组大小的表达式为

printf("Hello, World!\n")

此表达式的结果为int类型,并且是传输的字符数(如果有错误,则为负值)。
如果数组中的[]表达式不是常量,例如printf表达式,则该数组为变长数组。这些数组也可以用作函数参数的类型。
可变长度数组是在C99中引入C的一个功能,尚未在C++中引入。

ifmq2ha2

ifmq2ha22#

如错误消息所示,main需要char**作为其第二个参数。但是,由于数组衰减规则,以下两个参数都可以:

int main(int argc, char** argv);   // OK
int main(int argc, char* argv[]);  // OK

事实上,以下也是等价的,因为数组衰减不关心维数:

int main(int argc, char* argv[5]); // OK

然而,**尽管在C99中数组可能具有可变长度,但在C++中 * 不是这样。因此,对该数组维度使用非常数表达式(在您的示例中为printf("Hello world\n"))是无效的语法。

int main(int argc, char* argv[printf("Hello, world!\n")]); // Not OK!

这种无效的语法会使解析器混淆,并在编译器中导致这种误导性错误。
如果您稍微简化代码以删除function-call-expression(但仍使用非常数作为数组边界),则you get a far more relevant error message

int x = 5;
int main(int argc, char* argv[x]) {}
// error: array bound is not an integer constant

实际上,GCC 4.1.2 gives this useful message for your original code, too,所以你的编译器一定是 * 真的 * 旧了...要么是这样,要么是你的测试用例坏了despite the far newer GCC 4.5.1 yielding the message you posted

kyxcudwk

kyxcudwk3#

在C语言中,char *argv[some_expression]是一个可变长度的数组,因此当它作为函数参数时,被解释为一个指针(就像一个固定长度或未知长度的数组在声明函数参数时所做的那样)。
在C++中,不存在变长数组,所以它是无效的。char * argv[some_constant]char * argv[]都是有效的,并且等价于char ** argv--但是当然,这些都不会有副作用,所以不能用来解决那个愚蠢的练习。

相关问题