views:

429

answers:

10
+2  A: 

It looks to me like a problem with your particular compiler. It doesn't give an error with the compilers I have handy.

Jerry Coffin
<iostream> definitely does not define a symbol `random` in global namespace.
gimpf
But as pointed out below, it could include a posix header blablablah, , but why is random required for iostream functionality??
gimpf
@gimpf:<iostream> definitely *shoudln't* define a symbol `random` in the global namespace.
Jerry Coffin
@gimpf:`random()` almost certainly isn't needed for iostream functionality. My guess would be that they include something like `<stdlib.h>` for something like a definition of `size_t`, and that particular version of `<stdlib.h>` also happens to define `random()`.
Jerry Coffin
@Jerry: Meaning that somebody got careless. Including standard headers should not result in defining nonstandard symbols.
David Thornley
@David:the joy of standards is that there are so many to choose from! Just for example, POSIX requires some standard headers to define things that the C standard says those same headers must *not* define. If memory serves, that's now handled by saying they should only be defined if you've defined `_POSIX_SOURCE` (or somesuch), but quite a bit of code expects to work without that, and the compiler is stuck in the middle, trying to cater to conflicting goals (though I tend to agree that less namespace pollution would generally be better).
Jerry Coffin
+8  A: 

Use a namespace

namespace myNamespace
{

    class random
    {
    public:
        random(){ std::cout << "yay!! i am called \n" ;}
    };

}

myNamespace::random r1;
karoberts
From the question: "I have tried using namespaces but that leads to ambiguity at the time of call."
Georg Fritzsche
It won't lead to ambiguity if you include the namespace in the call "static myNamespace::random r2;"
Patrick
The the poster must not be fully qualifying the type, as in "myNamespace::random"
karoberts
I can only imagine ambiguity errors for say `using myNamespace; static random r1;`.
Georg Fritzsche
+2  A: 

If you have name collision problems use a namespace:

namespace mydata{
 class random{things};
}

And then call it mydata::random;

Arkaitz Jimenez
+5  A: 

You're running into the POSIX random() function.

How do you avoid collisions? Know your libraries. Or you can do as I did to diagnose this, say man random. There it was, random(3).

I don't know what your namespace problem is, but it sounds like a separate question.

Warren Young
`random()` isn't Posix, I think it's BSD.
Steve Jessop
it is posix: CONFORMING TO 4.3BSD, POSIX.1-2001.
Matt Joiner
Right you are. Sorry for the confusion, I botched my attempt at a search on opengroup.org.
Steve Jessop
+1  A: 

To avoid these issues, use namespaces.. wikipedia

namespace myNamespace
{
     class random
     {
         ....
     };
}
Jack
+4  A: 

In the case of g++, use command line option -ansi. This removes the non-standard function random from stdlib.h.

By default, g++ compiles as -std=gnu++98, which is "The 1998 ISO C++ standard plus amendments plus GNU extensions". So your code has done nothing wrong in order to be portable. It's just that without -ansi, you aren't using a compliant compiler.

These BSD (and Posix) stdlib functions are among those GNU extensions. From the glibc documentation:

http://www.gnu.org/s/libc/manual/html%5Fnode/BSD-Random.html

"There is no advantage to using these functions with the GNU C library; we support them for BSD compatibility only."

In general, if you want to write code that's portable to non-compliant compilers, then you just have to memorise the peculiarities of every single compiler in the world. GCC and MSVC are good ones to start with. Even with -ansi, you can make gcc non-compliant with other command-line options, such as -O2. This happened with the -fdelete-null-pointer-checks fiasco that hit the linux kernel a while back). Same goes for platforms whose libraries "extend" C (and hence C++), like BSD and Posix.

The reason there's a C standard in the first place is supposed to be so that you don't have to worry about this stuff, and personally I think it's unfortunate that other standards mess with C standard headers. But I'd guess that the fact of those functions being in stdlib on BSD dates from before C89. If so, then presumably it avoided a breaking change on BSD and other unixes at the time.

Btw, I found out that random() was in stdlib.h with g++ -E, which is useful when you want to know what on earth the system headers are doing to your program. I assumed that searching the web for "random" would be pointless. But "stdlib random" worked quite well.

Steve Jessop
A: 

Are you including cstdlib? I get the error you show when I include it, I don't if I don't.

Liz Albin
A: 

the g++ compiler which i m using correctly compiled and ran your program. I m using MinGw 5.1.6 for running g++ on windows..

vaibhav
+1  A: 

In general you avoid ambiguity errors by resolving them explicitly. Without putting your duplicate symbol in another namespace this can't work (except for cases where elaborated type specifiers help as litb points out) as you have two symbols in the same namespace and can't refer to either of them explicitly.

When putting your symbol in a namespace, you can:

  • fully qualify the name: myNamespace::mySymbol(x);
  • explicitly resolve the ambiguity: using myNamespace::mySymbol;

Note that pulling all symbols from your namespace in via using myNamespace; doesn't help as this doesn't resolve the ambiguity.

For full qualification its common to use short-hand names:

namespace mns = myNamespace;
mns::mySymbol(x);
Georg Fritzsche
+2  A: 

Why does your using namespace... not work, while your using ... works? First i want to show you another way to solve it by use of an elaborated type specifier:

int main() {
  // ...
  static class random r2; // notice "class" here
  // ...
}

That works because "class some_class" is an elaborated type specifier, which will ignore any non-type declarations when looking up the name you specify, so the POSIX function at global scope, which has the same name, will not hide the class name. You tried two other ways to solve it: Using directives and using declarations:

  • Then, you tried to stick the type into a namespace, and tried using namespace foo; in main - why did it not work?

    namespace foo {
    class random
    {
     public:
     random(){ std::cout << "yay!! i am called \n" ;}
    };
    }
    
    
    int main() {
     using namespace foo; 
     static random r2; // ambiguity!
     return 0 ;
    }
    

    You might wonder why that is so, because you might have thought that the using directive declares the names of foo into the local scope of main - but that's not the case. It's not declaring any name, actually it's just a link to another namespace. It's making a name visible during unqualified name lookup in that case - but the name is made visible as a member of the namespace enclosing both the using-directive and the denoted namespace (foo). That enclosing namespace is the global namespace here.

    So what happens is that name lookup will find two declarations of that name - the global POSIX random declaration, and the class declaration within foo. The declarations were not made in the same scope (declarative region), and so the function name doesn't hide the class name as usual (see man stat for an example where it does), but the result is an ambiguity.

  • A using declaration however declares one name as a member of the declarative region that it appears in. So, when random is looked up starting from main, it will first find a name that refers to the declaration of random in foo, and this will effectively hide the global POSIX function. So the following works

    namespace foo {
    class random
    {
     public:
     random(){ std::cout << "yay!! i am called \n" ;}
    };
    }
    
    
    int main() {
     using foo::random; 
     static random r2; // works!
     return 0 ;
    }
    
Johannes Schaub - litb
+1 for comprehensiveness. Made me look up *elaborate type specifiers* in *§3.4.4*.
Georg Fritzsche
Maybe it would make sense to have a specific question on name lookups that one could refer to in the future? Didn't find any on SO.
Georg Fritzsche
nice explanation man!!! although i figured out some of it.. ;-)
Neeraj