Reputation: 1071
I have below discovery by chance. The compiler compiles the below code without any error or warning. Please help me understand why the compiler is not throwing any error? The program contains just a string in a double quotation.
I have not declared any char array neither assigned the below string to any variable.
void main()
{
"Why there is no error in compilation?";
}
Upvotes: 3
Views: 291
Reputation: 263297
void main()
{
"Why there is no error in compilation?";
}
First, let's address the string literal. An expression statement, which is valid in any context where any statement is valid, consists of an (optional) expression followed by a semicolon. The expression is evaluated and any result is discarded. (The empty statement, consisting of just a semicolon, is classified as an expression statement; I'm not sure why.)
Expression statements are very common, but usually used when the expression has side effects. For example, both assignments (x = 42;
) and function calls (printf("Hello, world\n")
) are expressions, and the both yield values. If you don't care about the result, just add a semicolon and you have a valid statement.
Not all expressions have side effects. Adding a semicolon to an expression that doesn't have any side effects, as you've done here (a string literal is an expression), is not generally useful, but the language doesn't forbid it. Generally C lets you do what you want and lets you worry about whether it makes sense, rather than imposing special-case rules that might prevent mistakes but could also prevent you from doing something useful.
Now let's cover void main()
. A lot of people will tell you, with some justification, that this is wrong, and that the correct definition is int main(void)
. That's almost correct, and it's excellent advice, but the details are more complicated than that.
For a hosted implementation (basically one that provides the standard library), main
may be defined in one of three ways:
int main(void) { /* ... */ }
or
int main(int argc, char *argv[]) { /* ... */ }
or equivalent, "or in some other implementation-defined manner." (See N1570 section 5.1.2.2.2 for the gory details.) That means that a particular implementation is permitted to document and implement forms of main
other than the two mandated forms. In particular, a compiler can (and some do) state in its documentation that
void main() { /* ... */ }
and/or
void main(void) { /* ... */ }
is valid for that compiler. And a compiler that doesn't explicitly support void main()
isn't required to complain if you write void main()
anyway. It's not a syntax error or a constraint violation; it just has undefined behavior.
For a freestanding implementation (basically one that targets embedded systems with no OS, and no requirement to support most of the standard library), the entry point is entirely implementation-defined; it needn't even be called main
. Requiring void main()
is not uncommon for such implementations. (You're probably using a hosted implementation.)
Having said all that, if you're using a hosted implementation, you should always define main
with an int
return type (and in C you should int main(void)
rather than int main()
). There is no good reason to use void main()
. It makes your program non-portable, and it causes annoying pedants like me to bore you with lengthy discussions of how main
should be defined.
A number of C books advise you to use void main()
. If you see this, remember who wrote the book and avoid anything written by that author; he or she doesn't know C very well, and will likely make other mistakes. (I'm thinking of Herbert Schildt in particular.) The great irony here is that void
keyword was introduced by the 1989 ANSI C standard -- the very same standard that introduced the requirement for main
to return int
(unless the implementation explicitly permits something else).
I've discussed the C rules so far. Your question is tagged both C and C++, and the rules are a bit different in C++. In C++, empty parentheses on a function declaration or definition have a different meaning, and you should write int main()
rather than int main(void)
(the latter is supported in C++, but only for compatibility with C). And C++ requires main
to return int
for hosted implementations, with no permission for an implementation to support void main()
.
Upvotes: 1
Reputation: 739
Compile the program with -Wunused-value
flag. It just raises
warning: statement with no effect
"Why there is no error in compilation?";
^
That is it.
And If you compile the above code with -Wall
flag it also says
warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main() {
Upvotes: 1
Reputation: 1812
Because any expression is a valid statement.
"Why is there no error in compilation?";
is a statement that consists of an expression that evaluates to the given literal string. This is a perfectly valid statement that happens to have no effect whatsoever.
Upvotes: 10
Reputation: 140457
Of course, "useful" statements look more like
a = b;
But well;
b;
is also a valid statement. In your case, b is simply string literal; and you are free to place that within a the body of a method. Obviously this statement doesn't have any side effects; but what if the statement would be something like
"some string " + someFunctionReturningString();
You probably would want that expression to be executed; and as side effect, that method to be called, wouldn't you?
Upvotes: 1