void main(...
vs
int main(...
The standard specifies "int main(...". I agree that what happens with void main becomes compiler dependent.
#include <stdio.h> void main () { printf("\nHello World!\n"); } $ gcc -o foo foo.c foo.c: In function `main': foo.c:2: warning: return type of 'main' is not `int' $ ./foo
In the example, the compiler warning MAY have indicated that it was overriding the void with in. Since the original poster was new coder, best that they learn the approved syntax.
int main(int argc, char *argv[])
The syntax: int main(int argc, char **argv) works, but most of the C books I have seen recommend the *argv[] version.
Bob Styma
On Mon, Oct 31, 2005 at 01:30:44PM -0600, STYMA, ROBERT E (ROBERT) wrote:
#include <stdio.h> void main () { printf("\nHello World!\n"); } $ gcc -o foo foo.c foo.c: In function `main': foo.c:2: warning: return type of 'main' is not `int' $ ./foo
In the example, the compiler warning MAY have indicated that it was overriding the void with in.
Perhaps, but I think the better and truer explanation is that it is simply impossible for a program not to return some sort of return value to the operating system... even if it isn't an intended one. Generally the OS will see whatever value is in the appropriate register at the end of execution and use that as the exit status, whether or not that's what the coder intended. The behavior isn't defined by the standard, as we've said; but practically speaking, I don't imagine it's very common to see any different behavior... ;-)
Since the original poster was new coder, best that they learn the approved syntax.
I don't disagree, but given that Dotan wrote the most basic form of Hello World, I'm assuming he hasn't yet been introduced to the ideas of function prototypes, or the C standards. I've no doubt that he'll learn those topics later though. For the time being, it is probably best that he follows the convention of his learning materials.
The trouble is, Brian offered a code correction involving more complicated ideas than Dotan will have seen just yet, and then offered an explanation for the correction which was patently false. I think if you're going to take the time to correct someone who is trying to learn, you should yourself be sure to be correct.
In practice, for simple programs such as "Hello World", the only practical reason to adhere to the standard with regard to main()'s return value is to avoid compiler warnings. There's really nothing wrong with it, other than that it violates the standard. But that is itself not a crime; there are times when it is quite useful to violate the standard, and even necessary, (ironically) to ensure maximum portability. :)
On 10/31/05, Derek Martin code@pizzashack.org wrote:
On Mon, Oct 31, 2005 at 01:30:44PM -0600, STYMA, ROBERT E (ROBERT) wrote:
#include <stdio.h> void main () { printf("\nHello World!\n"); } $ gcc -o foo foo.c foo.c: In function `main': foo.c:2: warning: return type of 'main' is not `int' $ ./fooIn the example, the compiler warning MAY have indicated that it was overriding the void with in.
Perhaps, but I think the better and truer explanation is that it is simply impossible for a program not to return some sort of return value to the operating system... even if it isn't an intended one. Generally the OS will see whatever value is in the appropriate register at the end of execution and use that as the exit status, whether or not that's what the coder intended. The behavior isn't defined by the standard, as we've said; but practically speaking, I don't imagine it's very common to see any different behavior... ;-)
Since the original poster was new coder, best that they learn the approved syntax.
I don't disagree, but given that Dotan wrote the most basic form of Hello World, I'm assuming he hasn't yet been introduced to the ideas of function prototypes, or the C standards. I've no doubt that he'll learn those topics later though. For the time being, it is probably best that he follows the convention of his learning materials.
The trouble is, Brian offered a code correction involving more complicated ideas than Dotan will have seen just yet, and then offered an explanation for the correction which was patently false. I think if you're going to take the time to correct someone who is trying to learn, you should yourself be sure to be correct.
In practice, for simple programs such as "Hello World", the only practical reason to adhere to the standard with regard to main()'s return value is to avoid compiler warnings. There's really nothing wrong with it, other than that it violates the standard. But that is itself not a crime; there are times when it is quite useful to violate the standard, and even necessary, (ironically) to ensure maximum portability. :)
Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D
Actually, I was trying to one-up the course by being a little prepared before the professor starts handing out assignments to compile ourselves. The university website only has Turbo C for download, they must suppose that everybody uses windows. So I wanted to have a compiler ready and working before I need it. I pieced that script together from something that I saw on the web. But you are right- I will soon learn all the different function types, etc... pray for me...
Dotan http://lyricslist.com/lyrics/artist_albums/141/culture_club.php Culture Club Song Lyrics
On Mon, Oct 31, 2005 at 01:30:44PM -0600, STYMA, ROBERT E (ROBERT) wrote:
The syntax: int main(int argc, char **argv) works, but most of the C books I have seen recommend the *argv[] version.
I meant to comment that these two different notations are functionally identical; an array name is nothing more than a pointer. For example, if we have the following code:
#include <stdio.h> void main (void){ char foo[] = "This is a string\n"; char *bar = foo; /* these expressions all print "T\n" */ printf("%c\n", foo[0]); printf("%c\n", *bar); printf("%c\n", bar[0]); printf("%c\n", *foo); /* these expressions all print "i\n" */ printf("%c\n", foo[2]); printf("%c\n", *(bar + 2)); printf("%c\n", bar[2]); printf("%c\n", *(foo + 2)); }
The results may surprise programming students:
$ gcc -o ptr ptr.c ptr.c: In function `main': ptr.c:2: warning: return type of 'main' is not `int' [ddm@archonis ~] $ ./ptr T T T T i i i i
In reality, foo[x] is just "syntactic sugar" for *(foo + x). This is called pointer math, and works properly regardless of the size and type of foo, so long as it was declared properly before being used.
[I'm very bored today...]
Derek Martin wrote:
On Mon, Oct 31, 2005 at 01:30:44PM -0600, STYMA, ROBERT E (ROBERT) wrote:
The syntax: int main(int argc, char **argv) works, but most of the C books I have seen recommend the *argv[] version.
I meant to comment that these two different notations are functionally identical; an array name is nothing more than a pointer. For example, if we have the following code:
Not true. Or rather, only partially true. In a variable declaration the two are *not* equivalent. In a parameter declaration and in an expression, the two *are* equivalent. The difference is, in a variable declaration, you also specify how much space is to be allocated for the variable, which is not the case for the other uses. So, the books are indeed correct, **argv and *argv[] are equivalent *when used in the parameter list*.
#include <stdio.h> void main (void){
char foo[] = "This is a string\n";
And this is totally different from char *foo = "This is a string\n"; The former declares an array and gives it a name, the latter declares an anonymous array (string) and creates a pointer to it. With the former declaration, you cannot alter the value of foo, with the latter you can (alter as in foo = some_other_value; or foo++;).
char *bar = foo; /* these expressions all print "T\n" */ printf("%c\n", foo[0]); printf("%c\n", *bar); printf("%c\n", bar[0]); printf("%c\n", *foo); /* these expressions all print "i\n" */ printf("%c\n", foo[2]); printf("%c\n", *(bar + 2)); printf("%c\n", bar[2]); printf("%c\n", *(foo + 2));}
The results may surprise programming students:
$ gcc -o ptr ptr.c ptr.c: In function `main': ptr.c:2: warning: return type of 'main' is not `int' [ddm@archonis ~] $ ./ptr T T T T i i i i
In reality, foo[x] is just "syntactic sugar" for *(foo + x). This is called pointer math, and works properly regardless of the size and type of foo, so long as it was declared properly before being used.
[I'm very bored today...]
On Mon, 31 Oct 2005, Derek Martin wrote:
On Mon, Oct 31, 2005 at 01:30:44PM -0600, STYMA, ROBERT E (ROBERT) wrote:
The syntax: int main(int argc, char **argv) works, but most of the C books I have seen recommend the *argv[] version.
I meant to comment that these two different notations are functionally identical; an array name is nothing more than a pointer. For example, if we have the following code:
#include <stdio.h> void main (void){
char foo[] = "This is a string\n"; char *bar = foo; /* these expressions all print "T\n" */ printf("%c\n", foo[0]); printf("%c\n", *bar); printf("%c\n", bar[0]); printf("%c\n", *foo);
/* ...and my favorite... */
printf("%c\n", 0[foo]);
/* these expressions all print "i\n" */ printf("%c\n", foo[2]); printf("%c\n", *(bar + 2)); printf("%c\n", bar[2]); printf("%c\n", *(foo + 2));
printf("%c\n", 2[foo]);
/* That's right, folks, [] is commutative! */
}
The results may surprise programming students:
$ gcc -o ptr ptr.c ptr.c: In function `main': ptr.c:2: warning: return type of 'main' is not `int' [ddm@archonis ~] $ ./ptr T T T T i i i i
In reality, foo[x] is just "syntactic sugar" for *(foo + x). This is called pointer math, and works properly regardless of the size and type of foo, so long as it was declared properly before being used.
[I'm very bored today...]
On Mon, 31 Oct 2005, Sjoerd Mullender wrote:
Derek Martin wrote:
On Mon, Oct 31, 2005 at 01:30:44PM -0600, STYMA, ROBERT E (ROBERT) wrote:
The syntax: int main(int argc, char **argv) works, but most of the C books I have seen recommend the *argv[] version.
I meant to comment that these two different notations are functionally identical; an array name is nothing more than a pointer. For example, if we have the following code:
Not true. Or rather, only partially true. In a variable declaration the two are *not* equivalent. In a parameter declaration and in an expression, the two *are* equivalent.
Not in all expressions. sizeof(array) is usually not sizeof(&array[0])
See me trim.
On Mon, 2005-10-31 at 16:36, Matthew Saltzman wrote:
I meant to comment that these two different notations are functionally identical; an array name is nothing more than a pointer. For example, if we have the following code:
#include <stdio.h> void main (void){
char foo[] = "This is a string\n"; char *bar = foo; /* these expressions all print "T\n" */ printf("%c\n", foo[0]); printf("%c\n", *bar); printf("%c\n", bar[0]); printf("%c\n", *foo);/* ...and my favorite... */
printf("%c\n", 0[foo]);/* these expressions all print "i\n" */ printf("%c\n", foo[2]); printf("%c\n", *(bar + 2)); printf("%c\n", bar[2]); printf("%c\n", *(foo + 2));printf("%c\n", 2[foo]);/* That's right, folks, [] is commutative! */
/* Or, if you have a strong stomach, simplify to: printf("%c\n", "This is a string\n"[2]) ; printf("%c\n", 2["This is a string\n"] ) ; /* It's all simple addition...*/
}