Reputation: 1483
I was just wondering about the content of question 'Hello, World!' in C without semicolons and without 'if', 'while', or 'for' statements.
The following code worked in C, but not in C++:
int main(int argc, char *argv[printf("Hello, World!\n")]) {}
In C++, I get this error:
error: expected ‘,’ or ‘...’ before ‘argv’|
warning: second argument of ‘int main(int, char*)’ should be ‘char **’ [-Wmain]|
||=== Build finished: 1 errors, 1 warnings ===|
Why is it not working in C++?
Upvotes: 7
Views: 642
Reputation: 145839
Because C++ doesn't have any variable-length array feature.
The argv
parameter in
char *argv[printf("Hello, World!\n")]
is a variable-length array.
The expression that specify the size of the array is
printf("Hello, World!\n")
The result of this expression is of type int
and is the number of characters transmitted (or a negative value if there is an error).
An array where the expression in the []
is not constant, like in the example the printf
expression, is a variable-length array. Those arrays also are permitted to be used as the type of a function parameter.
A variable-length array is a feature introduced in C in C99 and has not been introduced in C++.
Upvotes: 19
Reputation: 385174
As the error message indicates, main
expects char**
for its second argument. However, due to array decay rules, the following are both OK:
int main(int argc, char** argv); // OK
int main(int argc, char* argv[]); // OK
And, in fact, the following is also equivalent because array decay doesn't care about dimensions:
int main(int argc, char* argv[5]); // OK
However, whereas in C99 arrays may have variable length, this is not the case in C++. So using a non-constant expression for that array dimension — in your case, printf("Hello world\n")
— is invalid syntax.
int main(int argc, char* argv[printf("Hello, world!\n")]); // Not OK!
This invalid syntax is confusing the parser and causing this misleading error in your compiler.
If you simplify the code slightly to remove the function-call-expression (but still using a non-constant for array bounds) then 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
Actually, GCC 4.1.2 gives this useful message for your original code, too, so your compiler must be really old... either that or your testcase is broken despite the far newer GCC 4.5.1 yielding the message you posted.
Upvotes: 8
Reputation: 254471
In C, char *argv[some_expression]
is a variable-length array, and so when used as a function argument is interpreted as meaning a pointer (just as a fixed-length or unknown-length array does when declaring a function argument).
In C++, variable-length arrays do not exist, so it's not valid. char * argv[some_constant]
and char * argv[]
, are both valid, and equivalent to char ** argv
- but of course none of these can have side effects, and so can't be used to solve that silly exercise.
Upvotes: 3