LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-19-2009, 12:08 PM   #1
Jeebizz
Senior Member
 
Registered: May 2004
Distribution: Slackware15.0 64-Bit Desktop, Debian 11 non-free Toshiba Satellite Notebook
Posts: 4,196

Rep: Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386
A bit quirky (C++ under Linux)


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)

For example:

Code:
#include <iostream>

using namespace std; 
void main()

{
     cout<<"Hello World!"<<endl;
}
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?

Last edited by Jeebizz; 02-19-2009 at 12:09 PM.
 
Old 02-19-2009, 12:10 PM   #2
Nylex
LQ Addict
 
Registered: Jul 2003
Location: London, UK
Distribution: Slackware
Posts: 7,464

Rep: Reputation: Disabled
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.

gcc hello.cpp -lstdc++.

Last edited by Nylex; 02-19-2009 at 12:13 PM.
 
Old 02-19-2009, 12:19 PM   #3
Jeebizz
Senior Member
 
Registered: May 2004
Distribution: Slackware15.0 64-Bit Desktop, Debian 11 non-free Toshiba Satellite Notebook
Posts: 4,196

Original Poster
Rep: Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386
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.
 
Old 02-19-2009, 12:20 PM   #4
Nylex
LQ Addict
 
Registered: Jul 2003
Location: London, UK
Distribution: Slackware
Posts: 7,464

Rep: Reputation: Disabled
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.
 
Old 02-19-2009, 12:26 PM   #5
Jeebizz
Senior Member
 
Registered: May 2004
Distribution: Slackware15.0 64-Bit Desktop, Debian 11 non-free Toshiba Satellite Notebook
Posts: 4,196

Original Poster
Rep: Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386
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.
 
Old 02-19-2009, 12:30 PM   #6
Nylex
LQ Addict
 
Registered: Jul 2003
Location: London, UK
Distribution: Slackware
Posts: 7,464

Rep: Reputation: Disabled
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.
 
Old 02-19-2009, 12:47 PM   #7
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
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.
 
Old 02-19-2009, 02:21 PM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Jeebizz View Post
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.
 
Old 02-19-2009, 07:16 PM   #9
Jeebizz
Senior Member
 
Registered: May 2004
Distribution: Slackware15.0 64-Bit Desktop, Debian 11 non-free Toshiba Satellite Notebook
Posts: 4,196

Original Poster
Rep: Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386
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?
 
Old 02-19-2009, 07:40 PM   #10
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by Jeebizz View Post
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.
 
Old 02-19-2009, 07:49 PM   #11
Jeebizz
Senior Member
 
Registered: May 2004
Distribution: Slackware15.0 64-Bit Desktop, Debian 11 non-free Toshiba Satellite Notebook
Posts: 4,196

Original Poster
Rep: Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386
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?
 
Old 02-20-2009, 05:22 AM   #12
Biddle
Member
 
Registered: Jan 2009
Posts: 37

Rep: Reputation: 17
Quote:
that using namespace std; is a way to guarantee that there won't be any namespace conflicts
Code:
using namespace std::tr1;
using namespace boost;

int main()
{
 shared_ptr<int> i;//which shared_ptr is this?
}
This is just one of many problems that users that write code like this will find, either now or in the not to distant future.
 
Old 02-20-2009, 06:32 AM   #13
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Jeebizz View Post
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.
 
Old 02-20-2009, 09:21 AM   #14
Jeebizz
Senior Member
 
Registered: May 2004
Distribution: Slackware15.0 64-Bit Desktop, Debian 11 non-free Toshiba Satellite Notebook
Posts: 4,196

Original Poster
Rep: Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386Reputation: 1386
Quote:
Originally Posted by Sergei Steshenko

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 .
 
Old 02-20-2009, 11:58 AM   #15
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by Jeebizz View Post
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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Quirky Trash Error DragonSlayer48DX Ubuntu 1 02-10-2009 06:10 AM
quirky OS or irresponsible sys admin? edsmithers Linux - Newbie 1 11-24-2003 03:47 PM
Quirky Mozilla Behavior Comatose51 Linux - Software 2 05-01-2003 03:20 PM
quirky comments upon logging in N_A_J_M Linux - General 2 04-17-2003 06:52 AM
X Crash *quirky this one is* DaFrEQ Linux - General 5 10-31-2002 02:14 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:14 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration