Skip to main content
GameDev.net gamedev.net
🔒 Locked

C++ - Whats the most up-to-date form of "Hello World"?

Started by Kaycon11 Jul 19, 2008 at 12:28 AM 38 replies 7.3k views
Original Post
Kaycon11
Kaycon11
I am just curious, I am learning C++ right now from a book called "C++ How to program 2005", But when I type in the code for hello world, I have to make a blank console project because the WIN32 console preset is way different then whats in the book. Plus when I do make a blank project it says the program is outdated. Here is the code they give for it. 1 // Fig. 2.1: fig02_01.cpp 2 // Text-printing program. 3 #include 4 5 // 6 int main() 7 { 8 std::cout << "Welcome to C++!\n"; 9 10 return 0; 11 12 } --------------------------------------------- The code of the preset WIN32 console application starts out like this... // HW.cpp : Defines the entry point for the console application. // #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { return 0; } ---------------------------------------------- So, basically, what I am trying to ask is, How would make the screen say "Hello World!", in this second code here, the most up-to-date WIN32 Console way, I guess...
-----------------------------------------"With the mind, anything is possible"
ToohrVyk
ToohrVyk
The most basic "hello world" program in C++ is a program that outputs "Hello World" to the standard output, and then exits without error. This is accomplished with:

#include <iostream>int main(){  std::cout << "Hello, World!\n";}


Note the absence of a return statement in the main function, since it's implicitly added by the compiler (although I suspect the book kept it there to keep you from being confused).

By compiling a file containing this code, you should get a working program with no errors. If you get any errors, you might have a problem with your compiler configuration, so post the exact error here. In practice, the default code in most IDEs is useless (especially to a beginner) so use empty projects as often as you can.
Degra
Degra
Quote:
Original post by Kaycon11
Here is the code they give for it.

1 // Fig. 2.1: fig02_01.cpp
2 // Text-printing program.
3 #include
4
5 //
6 int main()
7 {
8 std::cout << "Welcome to C++!\n";
9
10 return 0;
11
12 }
---------------------------------------------


I'm surprised that a recent C++ book didn't use..
std::cout << "Welcome to C++!" << std::endl;
Coldon
Coldon
your first method is in c++, the second method is in visual c++ - to an extent the same language but also not.

i'm not sure why it says your project is outdated unless you're making changes then hitting the big green play button, then you'll get a message about your project being outdated and whether it should rebuild. (I'm kinda speaking off of the top of my head cause i just click the don't notify me again checkbox the first time it appears)

for c++ in visual studio:

file -> new -> project -> empty project

if you want a really excellent c++ book get jesse liberty's learn to program c++ in 21 days! Out of all the beginner c++ books I've seen its by far the best!
"In theory, theory and practice are the same. In Practice, they never are."
My Technical Blog : http://www.takinginitiative.net/
ToohrVyk
ToohrVyk
Quote:
Original post by Degra
I'm surprised that a recent C++ book didn't use..
std::cout << "Welcome to C++!" << std::endl;


Because it would be pointless: adding the newline to the string is shorter, and the implicit stream flush caused by std::endl would happen anyway as the program ends and sends an end-of-stream to the standard output.
Splinter of Chaos
Splinter of Chaos
It's still better practice to use endl. The only time it's ever helped me is when my program crashed before the stream flushed, but it's good practice so you don't EVER run into that problem. Especially since using cout to test for errors, then not having the stream flush defeats the whole purpose of using cout to test for errors!

The escape sequence is good for safe, non-crashable code, but since we'd like to think of all code as non-crashable, it's always better to use endl.
the_edd
the_edd
Quote:
Original post by Splinter of Chaos
It's still better practice to use endl. The only time it's ever helped me is when my program crashed before the stream flushed, but it's good practice so you don't EVER run into that problem. Especially since using cout to test for errors, then not having the stream flush defeats the whole purpose of using cout to test for errors!

The escape sequence is good for safe, non-crashable code, but since we'd like to think of all code as non-crashable, it's always better to use endl.


Then super-strictly speaking, you also need to #include for std::endl, because it doesn't have to be declared by .
Spoonbender
Spoonbender
Quote:
Original post by Splinter of Chaos
It's still better practice to use endl. The only time it's ever helped me is when my program crashed before the stream flushed, but it's good practice so you don't EVER run into that problem. Especially since using cout to test for errors, then not having the stream flush defeats the whole purpose of using cout to test for errors!

The escape sequence is good for safe, non-crashable code, but since we'd like to think of all code as non-crashable, it's always better to use endl.


Except for two things.

First, this was supposed to be a minimal Hello World program. And the code shown above doesn't need std::endl to correctly print Hello World.

And second, flushing your stream all the time carries a performance cost. Usually, not a problem (and as you say, in cases where you use it for debug output, you *want* to flush after every statement), but if you're printing out a lot of text, and it's not just for debugging purposes, it's a lot better to just flush once, at the end, and not at every line break.
ToohrVyk
ToohrVyk
Quote:
Original post by Splinter of Chaos
It's still better practice to use endl. The only time it's ever helped me is when my program crashed before the stream flushed, but it's good practice so you don't EVER run into that problem. Especially since using cout to test for errors, then not having the stream flush defeats the whole purpose of using cout to test for errors!
The screwdriver not being heavy enough defeats the whole purpose of using a screwdriver to hit nails!

So, you're using std::cout to test for errors, find it inadequate because it buffers output, and thus apply the std::endl band-aid to make it fit, and then you advertise the resulting brittle contraption as best practice? Sorry, but no thanks.

The first issue with this is that you're using bad language-level tools. Given that std::cout was not designed for testing errors, and std::cerr was, using the former instead of the latter strikes me as a poor choice. Especially given that, since std::cerr is unbuffered, you don't have any stream-not-flushed issues! But even if we assume for a moment that you like std::cout more (why anyone would write error-testing text to the standard output stream instead of the standard error stream is beyond me), you can remove the buffering on std::cout using std::cout.rdbuf()->pubsetbuf(0,0); and this avoid to write all these annoying std::endl everywhere!

The second issue is that you're using bad development tools. For all intents and purposes, any situation in which you can afford write error-testing junk to the standard output is a situation where you have your compiler available. And, by extent, you can instead use the debugger available on your development computer to determine the exact position of the error, because this is precisely what it was designed for and is an order of magnitude more efficient that looking for the error by hand using logging code. The only situation where I would see debug-by-logging-strings as a good practice would be developing for an embedded device where no remote debugging is available, and that situation is so rare that it's hardly relevant when deciding what a best practice is (and even then, you should be using an unbuffered stream anyway).

The third issue is that the scope of this "best practice" is way too limited. The vast majority of text being output in a non-trivial professional program is output to an unspecified stream (because this allows outputting that text to a file, to a stringstream, or to any of the standard streams) usually by implementing operator<< for a custom object. And, trust me, you don't want to flush every line when you're writing a 100-megabyte file to disk, thus flushing should not be used in the vast majority of cases, let alone std::endl.

Quote:
The escape sequence is good for safe, non-crashable code, but since we'd like to think of all code as non-crashable, it's always better to use endl.
Even if I had agreed with the previous discussion, I have a real hard time picturing a Hello World application as code that could crash in-between two string outputs. Good practices should be applied thoughtfully, not automatically, lest they become applied to situations where they do not fit. Namely, in a Hello World situation, std::endl provides no benefit, but makes the code longer and slightly more complex.
Ezbez
Ezbez
Quote:
Original post by Coldon
your first method is in c++, the second method is in visual c++ - to an extent the same language but also not.


I'm no expert, but this doesn't sound right to me. Can someone confirm? Isn't the OP just using the Win32 library, not some "C++-variant", and that this code could work on any compiler that Win32 supported.

@ToohrVyk: printf-ing/cerr-ing are sometimes necessary for debugging. For example, my robotics team must use them, since we have no debugger available for the compiler that we're using. And even if we could, we can't exactly use a breakpoint in the middle of the robot crashing into the wall - what would you expect the motors to do?
Decrius
Decrius
Quote:
Original post by Splinter of Chaos
It's still better practice to use endl. The only time it's ever helped me is when my program crashed before the stream flushed, but it's good practice so you don't EVER run into that problem. Especially since using cout to test for errors, then not having the stream flush defeats the whole purpose of using cout to test for errors!


I generally avoid std::endl, and use "<< '\n';" instead. If I want the text to be written away immediatly (that is, when I'm looking for errors) I use std::cerr (or std::clog).

[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
ToohrVyk
ToohrVyk
Quote:
Original post by Ezbez
@ToohrVyk: printf-ing/cerr-ing are sometimes necessary for debugging. For example, my robotics team must use them, since we have no debugger available for the compiler that we're using. And even if we could, we can't exactly use a breakpoint in the middle of the robot crashing into the wall - what would you expect the motors to do?


Quote:
Original post by ToohrVyk
The only situation where I would see debug-by-logging-strings as a good practice would be developing for an embedded device where no remote debugging is available, and that situation is so rare that it's hardly relevant when deciding what a best practice is (and even then, you should be using an unbuffered stream anyway).

dmatter
dmatter
Feel free to delete all the extra preset stuff like the stdafx.h file, and the code in HW.cpp, and replace it with the code from the book - or just use a blank project.

The code you've been provided with as default isn't really portable, whereas the book is demonstrating entirely standard and portable C++. It isn't the case that one is more modern than the other, one is just more Microsoft specific.

If you did want to work around the preset stuff (it won't make the slightest bit difference to anything the book could reasonably wish to teach you) then this would work just as well:

#include "stdafx.h"#include <iostream>int _tmain(int argc, _TCHAR* argv[]){    std::cout << "Welcome to poorly-portable C++!\n";    return 0;}

Note, however, that you should generally prefer to write portable, standard, code.

As for the message about being out of date, that's probably the IDE telling you that your project code has changed (and so out of sync/date) with a previously compiled version. This is nothing to worry about, just recompile and all will be well, there's even a tickbox to indicate never to tell you again.
Antheus
Antheus
C++, the ultimate beginner language, where "Hello World" is a Master's thesis project.
bschneid
bschneid
Quote:
Original post by Ezbez
Quote:
Original post by Coldon
your first method is in c++, the second method is in visual c++ - to an extent the same language but also not.


I'm no expert, but this doesn't sound right to me. Can someone confirm? Isn't the OP just using the Win32 library, not some "C++-variant", and that this code could work on any compiler that Win32 supported.

Correct. Visual C++ is Microsoft's C++ environment and not at all a separate language. Win32 is an API for developing in Windows, just like DirectX is a graphical API. Perhaps Microsoft's compiler has slightly different expectations of the source code than some other compiler, but in no way has Microsoft created a separate and distinct language.
caseyd
caseyd
Quote:


// HW.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}


This is Windows fancy way of defining main. If you right click on _tmain or _TCHAR, and select "Go to Definition", you can see that these are just mapped to basic types. All of this has to do with UNICODE support in windows. Windows did not always have Unicode support, and when they added it in, they created the TCHAR mappings and routines to aid in the internationalization of programs. For the most part you don't have to worry about it all that much.

In C and C++, there are two basic character types, the ascii char and the wide character wchar_t. The difference is in the sizes. The char is too small to be able to represent all of the non-english speaking character sets. The wchar_t is large enough to represent these. If you have UNICODE defined, which in Visual C++ 2005 is, I am pretty sure, defined by default, the TCHAR is defined, in the end, as a wchar_t. If you disable Unicode support, the TCHAR is defined as a char.

Since you are just starting out, don't worry about any of this for now. Just now that there is a type called wchar_t, with functions that work on them.
Since you are coming at this from a C++ angle, note also that this is equivalent to using std::string, char based, or std::wstring, wchar_t based.
Just use regular char's and std::string to make things simple. Your book probably talks about this somewhere.

You can also avoid all of the TCHAR stuff in Visual C++ 2005, when creating a Console Application. Instead of clicking Finish in the Wizard, click Next, and select Console Application, and then check the box labeled "Empty Project". This will crate a Console Application more like you are expecting.

The Microsoft developers information can be found at http://www.msdn.com. Do a search for something there if you need more information on it. The examples there can be a little hard to understand at first because they use all of Microsofts mappings, and because of that, almost look like an entirely different language. Just remember that in the end it is all C++, and that there are just levels of abstraction here.


Good luck,
-Casey
RobTheBloke
RobTheBloke
Quote:
Original post by ToohrVyk
Quote:
Original post by Degra
I'm surprised that a recent C++ book didn't use..
std::cout << "Welcome to C++!" << std::endl;


Because it would be pointless: adding the newline to the string is shorter, and the implicit stream flush caused by std::endl would happen anyway as the program ends and sends an end-of-stream to the standard output.


but std::endl is not the same as '\n'. Use endl since it's portable, whereas '\n' is not (which is the entire reason why endl was added in the first place - i.e. on windows it's \n\r).


ToohrVyk
ToohrVyk
Quote:
Original post by RobTheBloke
but std::endl is not the same as '\n'. Use endl since it's portable, whereas '\n' is not (which is the entire reason why endl was added in the first place - i.e. on windows it's \n\r).


I'm in ur C++ Standardz, doubtin ur assertionz.

Quote:
The C++ Standard, 27.6.2.7
  namespace std {    template <class charT, class traits>      basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);  }  Effects:    Calls os.put(os.widen('\n')) then os.flush().  Returns:    os



So, no. EDIT: to expand a bit more on the \n versus \n\r versus \r issue, the programming language automatically transforms '\n' to the appropriate line terminator (Wikipedia ).
Decrius
Decrius
Quote:
Original post by RobTheBloke
Quote:
Original post by ToohrVyk
Quote:
Original post by Degra
I'm surprised that a recent C++ book didn't use..
std::cout << "Welcome to C++!" << std::endl;


Because it would be pointless: adding the newline to the string is shorter, and the implicit stream flush caused by std::endl would happen anyway as the program ends and sends an end-of-stream to the standard output.


but std::endl is not the same as '\n'. Use endl since it's portable, whereas '\n' is not (which is the entire reason why endl was added in the first place - i.e. on windows it's \n\r).


On windows it's actually \r\n (not \n\r :P), but it works on windows. Probably not on Mac, since they use \r. So if you use \r\n for every new line, you should be fine...

[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
jpetrie
jpetrie
Quote:

but std::endl is not the same as '\n'. Use endl since it's portable, whereas '\n' is not (which is the entire reason why endl was added in the first place - i.e. on windows it's \n\r).

This isn't entirely accurate. endl isn't the same as \n, yes -- but as said before, it carries a performance overhead. It should not be globally subsituted.

'\n' isn't the ASCII newline. '\n' is the newline in the C++ basic source character set, which you can find described in section 2.2 of the standard. As part of translation, the source character set entities are converted to the execution character set in an implementation-defined manner. The basic character set is intended to map to the ASCII set, but need not do so exactly -- in particular this allows for additional portability -- in C++ '\n' should (assuming intelligent implementations) become the platform-specific proper newline sequence.

However, it should be noted that is does not appear to be how \n ends up being 'correct' on VC++:

#include <fstream>int main() {  std::ofstream f("f.txt");  f << "\n";}

produces a two-byte file containing the hexadecimal values 0x0D 0x0A under VC++ 2008, which is the behavior of least surprise (e.g., it just worked).

However, the VC++ compiler documentation indicates that the source and execution sets are ASCII. And in fact, if you examine the executable producted by VC++ -- particularly the section containing constant string storage -- for the above program, you discover that the string encoded as 0x0D 0x0A doesn't exist -- but 0x0A does. Character translation did not change the value of the token; this is a 'good thing' because then strlen("\n") and the like would not have reliable behavior; it seems that in order to provide the intended measure of portability with respect to the C++ '\n' token, the VC++ team implement the conversion as a library feature. It gets converted when writing to files, but not otherwise, so the result is essentially that '\n' can be used to achieve correct, portable newlines in C++.

Quote:

On windows it's actually \r\n (not \n\r :P), but it works on windows. Probably not on Mac, since they use \r. So if you use \r\n for every new line, you should be fine...

In light of what I said above, you actually should not do this. It will produce a file containing 0x0D 0x0D 0x0A for every occurance of '\r\n' -- just use '\n' for portable newlines. Decent compilers will translate when appropriate or (in the case of Windows, which is the oddball in that it includes a two-chacacter sequence) have a library-level solution to making it behave as intended by the C++ standard.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.