I've done Hello World programs with Visual C++ Express 2010 before, but I always checked the "Empty Project" option. This time I selected a Console project and took the defaults. Program is below.

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

using namespace std;
#include "stdafx.h"



int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World\n";
    return 0;
}

Errors are..

  1. Error : Name must be a namespace name (refers to "std" on line 4)
  2. error C2065: 'cout' : undeclared identifier

#2 is pretty obvious given number 1. I'm pretty new to Visual Studio 2010 except for Empty console projects. Figure I'd check it out. The whole "tmain" and "stdafx.h" aspect is new to me, but I figured I'd try it out. Do I need to configure something to make it find namespace std?

Recommended Answers

All 10 Replies

Isn't the std namespace part of iostream? #include <iostream> should do it.

Also, I found this:
_tmain is a macro that expand to main o wmain according to _UNICODE macro. In
VC2005, By default , a program is unicode enabled (UNICODE and _UNICODE defined)
so your _tmain macro expands to wmain (not main) and _TCHAR expands to wchar_t.

stdafx is a precompiled header, it should be under the header files of your project explorer and you can see what it includes.

I got a warning that iostream was redundant because of stdafx.h so I removed it.

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

using namespace std;
#include <iostream>
#include "stdafx.h"



int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World\n";
    return 0;
}
------ Build started: Project: HelloWorld, Configuration: Debug Win32 ------
  HelloWorld.cpp
c:\documents and settings\vern\my documents\visual studio 2010\projects\helloworld\helloworld\helloworld.cpp(5): warning C4627: '#include <iostream>': skipped when looking for precompiled header use
          Add directive to 'StdAfx.h' or rebuild precompiled header
c:\documents and settings\vern\my documents\visual studio 2010\projects\helloworld\helloworld\helloworld.cpp(12): error C2065: 'cout' : undeclared identifier
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Including stdafx.h before anything else seems to work, hopefully somebody will explain that because I don't know why.

You're right. Changing the order a bit seems to do the trick. Works now. Thanks. I'll leave it unsolved in case someone can chime in on why.

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

#include "stdafx.h"
#include <iostream>
using namespace std;



int _tmain(int argc, _TCHAR* argv[])
{
    cout << "Hello World\n";
    return 0;
}

Changing the order a bit seems to do the trick. Works now.

It works for the same reason that prototypes work the way they do. If you have a using directive, it applies to everything below the directive, but not above it. Here's an example that takes advantage of this behavior:

#include <ctime>
#include <limits>
#include <random>

namespace jsw {
    template <typename IntT = unsigned, typename EngineT = std::mt19937>
    class mtrand {
        EngineT _engine;
        std::uniform_int_distribution<IntT> _gen;
    public:
        mtrand(const IntT& lbound = std::numeric_limits<IntT>::min(), 
               const IntT& ubound = std::numeric_limits<IntT>::max())
            : _engine((IntT)std::time(nullptr)), _gen(lbound, ubound)
        {}

        IntT operator()() { return _gen(_engine); }
    };
}

#include <algorithm>
#include <iostream>
#include <iterator>

using namespace std;

int main()
{
    jsw::mtrand<int> rgen(0, 99);
    
    // Use a lambda instead of rgen directly to avoid copying
    generate_n(ostream_iterator<int>(cout, "\n"), 10, [&] { return rgen(); });
}

Two things of note are that the headers are mixed with code, and that the using directive is prior to main, but after the definition of mtrand. This means that mtrand cannot use any names in <algorithm>, <iostream>, or <iterator>, and must explicitly qualify for namespace std. The idea is that the above is easier to work on during initial library development, but by adding inclusion guards, the first part can be split into a header without any headache at all:

#ifndef JSW_MTRAND_H
#define JSW_MTRAND_H

#include <ctime>
#include <limits>
#include <random>

namespace jsw {
    template <typename IntT = unsigned, typename EngineT = std::mt19937>
    class mtrand {
        EngineT _engine;
        std::uniform_int_distribution<IntT> _gen;
    public:
        mtrand(const IntT& lbound = std::numeric_limits<IntT>::min(), 
               const IntT& ubound = std::numeric_limits<IntT>::max())
            : _engine((IntT)std::time(nullptr)), _gen(lbound, ubound)
        {}

        IntT operator()() { return _gen(_engine); }
    };
}

#endif
#include <algorithm>
#include <iostream>
#include <iterator>
#include "jsw_mtrand.h"

using namespace std;

int main()
{
    jsw::mtrand<int> rgen(0, 99);
    
    // Use a lambda instead of rgen directly to avoid copying
    generate_n(ostream_iterator<int>(cout, "\n"), 10, [&] { return rgen(); });
}
commented: Good example. +15

It works for the same reason that prototypes work the way they do. If you have a using directive, it applies to everything below the directive, but not above it. Here's an example that takes advantage of this behavior:

#include <ctime>
#include <limits>
#include <random>

namespace jsw {
    template <typename IntT = unsigned, typename EngineT = std::mt19937>
    class mtrand {
        EngineT _engine;
        std::uniform_int_distribution<IntT> _gen;
    public:
        mtrand(const IntT& lbound = std::numeric_limits<IntT>::min(), 
               const IntT& ubound = std::numeric_limits<IntT>::max())
            : _engine((IntT)std::time(nullptr)), _gen(lbound, ubound)
        {}

        IntT operator()() { return _gen(_engine); }
    };
}

#include <algorithm>
#include <iostream>
#include <iterator>

using namespace std;

int main()
{
    jsw::mtrand<int> rgen(0, 99);
    
    // Use a lambda instead of rgen directly to avoid copying
    generate_n(ostream_iterator<int>(cout, "\n"), 10, [&] { return rgen(); });
}

Two things of note are that the headers are mixed with code, and that the using directive is prior to main, but after the definition of mtrand. This means that mtrand cannot use any names in <algorithm>, <iostream>, or <iterator>, and must explicitly qualify for namespace std. The idea is that the above is easier to work on during initial library development, but by adding inclusion guards, the first part can be split into a header without any headache at all:

#ifndef JSW_MTRAND_H
#define JSW_MTRAND_H

#include <ctime>
#include <limits>
#include <random>

namespace jsw {
    template <typename IntT = unsigned, typename EngineT = std::mt19937>
    class mtrand {
        EngineT _engine;
        std::uniform_int_distribution<IntT> _gen;
    public:
        mtrand(const IntT& lbound = std::numeric_limits<IntT>::min(), 
               const IntT& ubound = std::numeric_limits<IntT>::max())
            : _engine((IntT)std::time(nullptr)), _gen(lbound, ubound)
        {}

        IntT operator()() { return _gen(_engine); }
    };
}

#endif
#include <algorithm>
#include <iostream>
#include <iterator>
#include "jsw_mtrand.h"

using namespace std;

int main()
{
    jsw::mtrand<int> rgen(0, 99);
    
    // Use a lambda instead of rgen directly to avoid copying
    generate_n(ostream_iterator<int>(cout, "\n"), 10, [&] { return rgen(); });
}

But why does stdafx.h have to be included at all? Why is it only present in console project?

But why does stdafx.h have to be included at all?

When precompiled headers are enabled, you need stdafx.h. It's a Visual C++ thing. I don't even waste my time with the console project, it's easier to start with an empty project and set it up the way I want.

Why is it only present in console project?

That's not the only place it's present, but the console project does use precompiled headers by default.

When precompiled headers are enabled, you need stdafx.h. It's a Visual C++ thing. I don't even waste my time with the console project, it's easier to start with an empty project and set it up the way I want.


That's not the only place it's present, but the console project does use precompiled headers by default.

Oh, so it has nothing to do with a dependence on some file? So the stdafx.h file could, in theory, be empty? With no system include files and it will compile fine?

So the stdafx.h file could, in theory, be empty?

In theory, sure.

With no system include files and it will compile fine?

Only if you explicitly include headers for the libraries you use. If stdafx.h is empty (in theory), then it does jack diddly as far as aiding compilation. It would be a glorified no-op.

Cool. Good to know. Much thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.