header file and 'using directive'

  • Thread starter subramanian100in
  • Start date
S

subramanian100in

Suppose the following is in Test.h

#ifndef TEST_H
#define TEST_H

#include <iostream>
#include <string>

using namespace std;

class Test
{
public:
Test(const string& str) : val(str)
{
cout << val << endl;
}

string val;
};
#endif

The above is accepted by the compiler. But generally 'using
declaration/directives' are not mentioned in header files. Why is it
so ?

Thanks
V.Subramanian
 
I

Ian Collins

Suppose the following is in Test.h

#ifndef TEST_H
#define TEST_H

#include <iostream>
#include <string>

using namespace std;
Don't.

You force the using directive on any file that includes the header.

Why to people get so obsessed with "using namespace std", rather than
simply using fully qualified names?
 
P

Pavel Shved

The above is accepted by the compiler. But generally 'using
declaration/directives' are not mentioned in header files. Why is it
so ?

Because when you include header file in your source code (that's the
same as copy-pasting whole header file there), the using directive
appears there as well, making std namespace unexpectedily visible to
your statemsnts without any qualifying.
 
I

Ivan Vecerina

: Suppose the following is in Test.h
:
: #ifndef TEST_H
: #define TEST_H
:
: #include <iostream>
: #include <string>
:
: using namespace std;
:
: class Test
: {
: public:
: Test(const string& str) : val(str)
: {
: cout << val << endl;
: }
:
: string val;
: };
: #endif
:
: The above is accepted by the compiler. But generally 'using
: declaration/directives' are not mentioned in header files.
: Why is it so ?

Because they go against the purpose of namespaces, creating
potential name collisions in all compilation units that
include the header.

Consider the following two example files:

//BobsLib.h
namespace BobsLib {
class runtime_error { ... };
...
}


//MySourceFile.cpp
#include "BobsLib.h"
#include "Test.h" // your file above

// My file intensively uses BobsLib
using namespace BobsLib;

void myFunction()
{
try {
//stuff using BobsLib...
}
catch( runtime_error& x ); //## ouch
// runtime_error ambiguous: std::~ or BobsLib::~ ?
}


Basically, but putting a using directive in the global
scope of a header file, you prevent all users of that
header from safely using that feature in their own code.
Not nice.


I hope this helps,
Ivan
 
A

Alf P. Steinbach

* (e-mail address removed), India:
generally 'using
declaration/directives' are not mentioned in header files. Why is it
so ?

Because the effect is not limited to the header file: it also affects
the client code including the header file.

Suppose the following is in Test.h

#ifndef TEST_H
#define TEST_H

#include <iostream>
#include <string>

using namespace std;

Bad, as explained above.

class Test
{
public:
Test(const string& str) : val(str)
{
cout << val << endl;
}

Breaks the separation-of-concerns design rule. As a general rule, don't
do i/o in constructors. And don't do i/o in functions or classes that
aren't specifically concerned with i/o.

The main rationale is the same as for the using directive, namely, to
not force things on client code.

E.g. stream i/o may not be welcome in a GUI application.

In addition, you don't have much control over where constructors are
called (or not).

Thus, i/o or other side-effects in a constructor is inherently unreliable.

string val;

A naming convention for members (or non-members) is often a good idea.

E.g., "myVal" or "val_".

};
#endif


Cheers, & hth.,

- Alf
 
O

osmium

Ian Collins said:
Why to people get so obsessed with "using namespace std", rather than
simply using fully qualified names?

Because doing the fully qualified things leads to an annoying thicket of
syntactic clutter. It's like talking to someone who peppers his
conversation liberally with "you know", of which there are tons. Some
people have minds apparently capable of effortlessly filtering out all kinds
of noise, some minds don't work that way. For the latter, the using
directive makes life bearable. Of course it must be used properly, which is
usually a good idea with almost any tool.

std::That std::is std::the std::eek:nly ::std::reason std::for std::the
std::usage std::you std::dislike std.
 
A

AnonMail2005

Suppose the following is in Test.h

#ifndef TEST_H
#define TEST_H

#include <iostream>
#include <string>

using namespace std;

class Test
{
public:
Test(const string& str) : val(str)
{
        cout << val << endl;

}

string val;};

#endif

The above is accepted by the compiler. But generally 'using
declaration/directives' are not mentioned in header files. Why is it
so ?

Thanks
V.Subramanian

I'm not sure if anyone mentioned this but the effect of a using
directive depends on where it is placed in a file. It applies
to subsequent code (whether in the same file or in a file that
is subsequently included). What this means is that putting
using directives in header files makes the directives effect
dependent on the order of includes!!!

Think about that for a moment. For small systems or systems
that have no namespaces and use only the std namespace you may
never run into an issue. But for medium size systems or systems
that use namespaces, this can easily cause extremely hard to
detect issues.

Many a Sutter book mentions this and has good code examples to
illustrate it.

HTH
 
J

James Kanze

Because doing the fully qualified things leads to an annoying
thicket of syntactic clutter. It's like talking to someone
who peppers his conversation liberally with "you know", of
which there are tons. Some people have minds apparently
capable of effortlessly filtering out all kinds of noise, some
minds don't work that way.

I think the problem is in that statement. Some people may
consider it noise, but as far as I'm concerned, the name of the
object is std::cout. The std:: is no more "noise" than is the
"Kanze" in my name. There are contexts where just using "James"
when talking about me may be acceptable, but in general, if you
want your reader to know exactly who you're talking about,
you'll use "James Kanze". Or std::cout.
 
J

James Kanze

* (e-mail address removed), India:

[...]
Breaks the separation-of-concerns design rule. As a general
rule, don't do i/o in constructors. And don't do i/o in
functions or classes that aren't specifically concerned with
i/o.

That probably applies to this type of I/O (and it certainly
applies to std::cout), but I regularly use constructors which
construct objects from persistent store. I think it's a
standard technique when objects should be persistent.

Logging is also appropriate in constructors for application
level classes. Logging definitly involves I/O as well (although
it shouldn't be as direct as this).
The main rationale is the same as for the using directive,
namely, to not force things on client code.
E.g. stream i/o may not be welcome in a GUI application.
In addition, you don't have much control over where
constructors are called (or not).

That's true for objects with value semantics (and then probably
only for the copy constructor), but again, there are large
classes of objects which don't support copy construction. And
of course, the constructor which reads from persistent store is
probably called with the input stream as an argument---you
certainly have total control over where it is called.
Thus, i/o or other side-effects in a constructor is inherently
unreliable.

When reading from persistent store, that's what exceptions are
for (although in specific cases, other strategies may also be
appropriate). When writing to a log, if the write fails, it
fails---your application still works.

Note well that I don't approve outputting to std::cout in a
constructor, at least in production code. I can't ever think of
a case in production code where that would appropriate. (On the
other hand, if you want to write a quick test to see whether
your compiler does NRVO in a specific case...)
 
D

Daniel T.

Ian Collins said:
Don't.

You force the using directive on any file that includes the header.

Why to people get so obsessed with "using namespace std", rather than
simply using fully qualified names?

Because, refusing to use the using directive at all goes against the
purpose of namespaces. It puts us back in the bad old days when we had
to put nonsense letters at the beginning of every identifier to save us
from package collisions.
 
I

Ian Collins

Daniel said:
Because, refusing to use the using directive at all goes against the
purpose of namespaces. It puts us back in the bad old days when we had
to put nonsense letters at the beginning of every identifier to save us
from package collisions.

But "using namespace std" appears to have become automatic for some,
which also goes against the purpose of namespaces! If you are going to
wite this in every file, why bother with the std namespace at all?
 
D

Daniel T.

Ian Collins said:
But "using namespace std" appears to have become automatic for some,
which also goes against the purpose of namespaces!

I don't agree. The purpose of namespaces is so that I can use two
libraries that were developed independently of each other, without
having to worry about collisions between those libraries. For example,
if I am using the barney library, and the fred library and they both
have a "Foo" identifier, the fact that they are in in different
namespaces will save me a whole lot of grief. If I'm not using two
different libraries that were developed independently of each other,
then a local using-directive is fine.
 
S

Sherman Pendley

Daniel T. said:
Because, refusing to use the using directive at all goes against the
purpose of namespaces.

Please re-read the thread subject and above messages. No one is suggesting
not to use using *at all*, just pointing out that it shouldn't be used in
a *header file*.

Using it in a .cpp file, where the scope of its effect is limited to the
file its in, is a different question entirely.

sherm--
 
D

Daniel T.

Sherman Pendley said:
Please re-read the thread subject and above messages. No one is
suggesting not to use using *at all*, just pointing out that it
shouldn't be used in a *header file*.

Some suggest that using-directives, even in the .cpp file, are a bad
idea. I was merely covering all the bases.
Using it in a .cpp file, where the scope of its effect is limited
to the file its in, is a different question entirely.

I agree. Funny though, where I work I am the only one who refuses to put
using-directives in headers. None of the programmers who put them in the
headers have ever been burned by it... They think I'm silly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top