ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am taking a java programming course at school, and that has rekindled my interest in learning C++. So I have decided to try to learn c++ by myself concurrently as I am taking my java course.
As for java, I don't have much of an issue after downloading the JDK package from /extra in the slackware ftp site.
My issue is with C++ and the way that it works under a *nix environment. For the most part, I have done C++ under dos and windows, and am familiar of how the program is compiled, but it seems just a little bit strange on linux.
I wrote a quick hello program just to get my mind going again on how programming under C++ works; however the compiler just doesn't seem to like it (but I KNOW it is syntactically correct, and everything is typed accurately)
Relatively straightforward right? Yet when I issue the command to compile with g++, it doesn't seem to like it.
Code:
slackuser@slacker:~$ g++ hello.cpp
hello.cpp:5: error: '::main' must return 'int'
slackuser@slacker:~$
So am actually REQUIRED to only use int main() ? But why!? If I compile the same exact code under Windows, it works. There is nothing wrong with this code. I am rather perplexed.
So I made the following modifications:
int main() instead of void main, and of course return 0;
Passed it through g++ and it compiles! I still don't understand why I can't just use void main() though .
I also thought that using namespace std; was only an issue with Visual Studio, but it seems g++ doesn't like it if I don't have that in my code.
And last but not least; GCC won't even compile my program at all! Yet the man pages states it is a C AND C++ compiler. I have to use g++ only?
Code:
slackuser@slacker:~$ gcc hello.cpp
/tmp/ccaqPFSh.o: In function `__static_initialization_and_destruction_0(int, int)':
hello.cpp:(.text+0x24): undefined reference to `std::ios_base::Init::Init()'
/tmp/ccaqPFSh.o: In function `__tcf_0':
hello.cpp:(.text+0x6b): undefined reference to `std::ios_base::Init::~Init()'
/tmp/ccaqPFSh.o: In function `main':
hello.cpp:(.text+0x8e): undefined reference to `std::cout'
hello.cpp:(.text+0x93): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
hello.cpp:(.text+0x9e): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
hello.cpp:(.text+0xa4): undefined reference to `std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))'
/tmp/ccaqPFSh.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status
slackuser@slacker:~$ g++ hello.cpp && ls *.out
a.out*
Of course my program is a.out which I have to read the man pages to actually get it to name it hello instead. g++ -o hello right?
So I guess my only question is this still:
Why can't I just use void main() instead of int main() for my simple hello program?
Why doesn't gcc like my code either way, but g++ does, even though gcc is supposed to be a C++ compiler too?
Presumably you have to use int main() because that's part of the C++ standard, to which g++ conforms I think. Edit: see this. You can use gcc to compile C++ code, but you need to link libstdc++, i.e.
I see. But, all other compilers I have seen, not just Visual Studio, but also Borland accepts void main() instead of just int main(). Hell, I guess I didn't expect g++ to be THAT strict, since even void main() is I thought was an acceptable way to program a simple hello world program. The only reason I preferred void main, is just so I don't have to return 0;, which I think is pointless anyways since it is just an output hello program. Its just one less line of code I have to type.
If it's C++, you don't need to include the "return 0;" line. The code will still compile without it. g++ may have an option to make it less strict, though I'm not sure.
You're right. I commented return 0; and it STILL compiles. Strange though, since you CANNOT get away with not returning 0 in Visual Studio or any other commercial compiler, so I assumed that without returning 0 after int, would be an invalid source code. Even at school it was told that your program would not compile if you did not return 0;, and it was true, it wouldn't. G++ is so strange. Doesn't seem like it follows standards to me though. Go figure... Or perhaps I am still thinking of the C89 standard. C99 I guess you don't have to return 0;.... Hrmm.
Yeah, unfortunately I don't know why it works without the return statement. Intel's C++ compiler also compiles the code without the return statement. Maybe someone else can explain this.
The C++ (and the C99) standards do not require that a 'return' value be given in the main() function. If a 'return' value is not provided, then the value 0 is assumed and returned automatically.
P.S. On most *nix systems that employ the use of GCC, by default, 'gcc' uses the C89 standards. Provide the option -std= to specify a different standard (e.g. gnu99 or c99). Note that GCC does not fully implement the C99 standards.
Last edited by dwhitney67; 02-19-2009 at 12:52 PM.
I see. But, all other compilers I have seen, not just Visual Studio, but also Borland accepts void main() instead of just int main(). Hell, I guess I didn't expect g++ to be THAT strict, since even void main() is I thought was an acceptable way to program a simple hello world program. The only reason I preferred void main, is just so I don't have to return 0;, which I think is pointless anyways since it is just an output hello program. Its just one less line of code I have to type.
Hrmm.
No, it isn't. Under UNIX-like system there is a tradition of return codes - 0 means success, non-zero means some kind of problem.
This allows to chain programs in scripts, and to make intelligent decision whether to continue or not.
I had to deal with a lot of crappy programs/scripts which did not have meaningful return values, and it was a pain in all parts of my body figuring out actual success/failure of the said programs/scripts.
Thanks very much for the Stroustrup link Nylex, just a slight error in the link 'yhttp://www.research.att.com/~bs/bs_faq2.html#void-main' No worries though I got the main link from it
As I said before that I mainly wanted to use void main() not to return but according to that link, it is bad practice so now I must make sure to never even consider it, even if I am using Visual Studio or an other compiler that allows it.
As far as not having to type return 0; at the end of my program, (GCC/G++) I will however decide to type it anyways, just to get myself in the habit of it, in case I find myself working with a compiler that WILL complain if I don't return 0; and not compile my code, and I won't know whats wrong with it even though the answer would be staring me right in the face.
I also will still keep 'using namespace std;' because I am so used to the classic cout and cin statements, that typing std::cout<< instead seems too weird for me. I am more confortable with the 'deprecated' form, since I have always learned it that way and luckily it is not something seen as bad practice,...I hope?
I also will still keep 'using namespace std;' because I am so used to the classic cout and cin statements, that typing std::cout<< instead seems too weird for me. I am more confortable with the 'deprecated' form, since I have always learned it that way and luckily it is not something seen as bad practice,...I hope?
I'd recommend to use "using std::cout;" but that depends on situation, because "using std::cout; using std::endl;, etc" quickly gets too long (although you won't need everything from std namespace anyway).
In general - you shouldn't put "using namespace xyz" into headers. Might produce problems, especially with std namespace (hard to track compilation errors in headers (even on visual studio) - just personal experience). However, "using namespace std;" is fine within one file if it is after #includes.
No, I always type using namespace std; AFTER the #include statement, but also before int main(). I thought that (at least according to C++ From the Ground Up (book)), that using namespace std; is a way to guarantee that there won't be any namespace conflicts, and as I said before not only std::cout<< seems weird, but also too long winded. After declaring using namespace std; ONCE after the #include statement(s), I am free to just use cout and cin and any other standard C++ statements without std::<statement>
Plus given the simple nature of the programs I am writing, I don't think I will have to worry about any conflicts. Speaking of the simplicity of my programming, at this point not only I don't have to worry about throwing any 'special' optimization flags with gcc, my only other question is, should I bother stripping the binary? What does stripping do anyways? Just make the binary itself smaller? Or does it also eliminate some kind of memory overhead? I would probably understand seeing a need to strip a binary if it is a more complex program, like maybe a file utility program, or media player program, etc; but should I even bother with my programs? If yes, why?
Thanks very much for the Stroustrup link Nylex, just a slight error in the link 'yhttp://www.research.att.com/~bs/bs_faq2.html#void-main' No worries though I got the main link from it
As I said before that I mainly wanted to use void main() not to return but according to that link, it is bad practice so now I must make sure to never even consider it, even if I am using Visual Studio or an other compiler that allows it.
As far as not having to type return 0; at the end of my program, (GCC/G++) I will however decide to type it anyways, just to get myself in the habit of it, in case I find myself working with a compiler that WILL complain if I don't return 0; and not compile my code, and I won't know whats wrong with it even though the answer would be staring me right in the face.
I also will still keep 'using namespace std;' because I am so used to the classic cout and cin statements, that typing std::cout<< instead seems too weird for me. I am more confortable with the 'deprecated' form, since I have always learned it that way and luckily it is not something seen as bad practice,...I hope?
It's not a good idea - regardless of language.
At the moment you import something, you get a risk of name conflict.
If you always use std::cout, std::cerr, std::cin, you don't.
By the way, in UNIX tradition you would more often need std::cerr than std::cout, but it's a separate issue. If you are interested, I can explain why.
Sure I would like to know. I may not totally understand but I never pass up interesting information .
Please have a look into this session:
Code:
sergei@amdam2:~/junk/cat_demo> ls -ltr
total 8
-rw-r--r-- 1 sergei users 2 2009-02-20 19:49 a.txt
-rw-r--r-- 1 sergei users 2 2009-02-20 19:49 b.txt
sergei@amdam2:~/junk/cat_demo> cat a.txt
a
sergei@amdam2:~/junk/cat_demo> cat b.txt
b
sergei@amdam2:~/junk/cat_demo> cat a.txt b.txt > a_and_b_concatenated.txt
sergei@amdam2:~/junk/cat_demo> cat a_and_b_concatenated.txt
a
b
sergei@amdam2:~/junk/cat_demo> cat a.txt b.txt c.txt > a_and_b_and_missing_c_concatenated.txt
cat: c.txt: No such file or directory
sergei@amdam2:~/junk/cat_demo> cat a_and_b_and_missing_c_concatenated.txt
a
b
sergei@amdam2:~/junk/cat_demo>
The point is that "cat: c.txt: No such file or directory" message was printed to stderr, _not_ to stdout, and this fact helped to preserve "sanity" of 'a_and_b_and_missing_c_concatenated.txt' file - the error message in _not_ in 'a_and_b_and_missing_c_concatenated.txt' and this is good.
So, the rule of thumb:
if you consider screen output of your program to be useful data like the one produced by 'cat', 'sed', 'awk', 'sort', 'ls' etc., i.e. by utilities typically used to pipe data from one to another on command line, then use stdout -> cout; if, OTOH, your messages are just diagnostic ones, use stderr -> cerr.
The vast majority of messages produced by my code goes to stderr for the above reason.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.