Namespaces and scope visibility issue - c++

I made a header file sampleheader.h with following code:
namespace sample_namespace
{
int add(int n1,int n2)
{
return (n1 + n2);
}
}
Now my main.cpp file is:
#include <iostream>
#include "sampleheader.h"
using namespace std;
int add(int n1, int n2)
{
return (n1 + n2);
}
int main(void)
{
using namespace sample_namespace;
//cout<<add(5,7);
}
The project is built with no warning if i leave that line commented.It is understandable because the local add() function is defined in the global scope and add() function is made visible in the scope of main(). So no name conflict happens.
However, if I remove the comments, I get the following error:
"Ambiguous call to overloaded function"
First of all there should be no name conflict at all as explained by me above (if I'm right). But, if at all there is a name conflict why is it that it is notified by compiler only when I call the function. Such type of error should be shown as soon as a name conflicts (if at all).
Any help is appreciated.

Well, you explained it yourself.
When you have both int add() and int sample_namespace::add() in scope, the call is ambiguous. The statement add() could mean either of them.
There is no conflict in the functions co-existing because one is int add() and the other is int sample_namespace::add(). This is the entire purpose of namespaces.
You just have to be clear when you write code that uses them. If you get rid of your using namespace directives and always write explicit code, then you won't run into a problem:
#include <iostream>
namespace sample_namespace {
int add(int n1, int n2) {
return (n1 + n2);
}
}
int add(int n1, int n2) {
return (n1 + n2);
}
int main() {
std::cout << sample_namespace::add(5,7);
}
(Also, defining non-inline functions in headers is A Bad Idea™.)

"using namespace" does not hide other implementations. What it does in this case is make it ambiguous.
You have both sample_namespace::add and ::add with the same signature. Since you don't explicitly say which one to use, the compiler can't tell.
Declaring both functions is legal and unambiguous (which is why the compiler only complains when you use the function).

The reason why it's legal to declare both functions like that is because you can call both unambiguously, by qualifying them. That's why you get an error only when you make an unqualified call. Up to that point, there is not even a theoretical problem.
Intentionally, using namespace X; shouldn't introduce ambiguity errors by itself. That would very much defeat the purpose of namespaces. The common using namespace std; introduces many names that you'd reasonbly define yourself as well.

You cannot shadow symbols like that, only variable names (which is a warning on most compilers, i.e. a bad idea). using directives aren't precise in any sense, which I think is the assumption that most people make.
using directives will import a symbol into the scope. for instance, you can do things like this:
namespace foo {
using namespace std;
}
foo::string val;
This sort of practice leads to some very annoying compiler errors to track down. Your simple example is clear where the error is. If you try doing it in a few hundred thousand lines of code, you will be much less pleased.
I would advise you not to acquire the habit of relying on the using directive. If you must, just do one type at a time.
using std::string;
Basically, this keeps you honest. And if there is a naming conflict, grep will take 30 seconds to uncover where the problem is.
If you just spend a couple weeks typing std:: in front of your types, you will get used to it. I promise that the amount of time you think you are saving is greatly exaggerated.

I think this is because of compiler-optimisation. When your string is commented - he saw, that there are some function, but you don't use it, so he discard it. And when he saw that function useful - he want to insert function call, but can't chose which one you want.

Related

What is Wrong with my Code in calling function in main?

#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> big_vector = {5,12,4,6,7,8,9,9,31,1,1,5,76,78,8};
vector<int> a = sub(big_vector);
cout<<a.size();
return 0;
}
vector<int> sub(vector<int> big_vector){
return {big_vector.begin() + 7, big_vector.end() - 2};
}
I get this error and do not know why
main.cpp:18:21: error: ‘sub’ was not declared in this scope
debugging and running different test
In C++ all objects must be declared before they are used.
vector<int> a = sub(big_vector);
Your reliable compiler reads this, and it has absolutely no clue, whatsoever, what this mysterious sub function is all about.
Human eyeballs that are owned by a carbon-based life form can easily see this function, later in the file. But your compiler is a beast of logic. It hasn't read that far ahead, into the source file. That's why, in C++, in this situation the function must be declared:
vector<int> sub(vector<int>);
Put this before the main function. The compiler reads this first, and learns all about this amazing function called sub(), which has one vector<int> parameter, and returns a vector<int> itself. So when it reads the contents of main(), which calls this function, it knows exactly what it's all about, and can proceed further.
Or, you can simply put the entire sub() function before the main() function. That'll work, too.

What is the purpose of having a function prototype in a function?

I will admit I have not kept up with the latest C/C++ releases but I was wondering why having a function prototype in a function is valid code? Is it related to lambda usage?
Here is sample code - this will compile/run on Visual Studio 2019 and g++ 5.4.0
int main()
{
int func(bool test);
return 0;
}
A code block may contain any number of declarations. And because a function prototype is a declaration, it may appear in a block.
Granted, it doesn't make much sense to do so logistically as opposed to declaring a function at file scope, but it's syntactically correct.
In that example the declaration is pointless. But in a more complex example it's not:
int main() {
int func(bool test);
func(true);
return 0;
}
That code is equivalent to the more usual formulation:
int func(bool test);
int main() {
int func(bool test);
func(true);
return 0;
}
except that the first one introduces the name func only inside the scope of main; the second one introduces the name into the global scope.
I occasionally use the first form when I don't want to scroll through the source file to figure out where to put the declaration; putting it in the function where it's going to be used is a quick-and-dirty solution. And if it's temporary code (adding debugging output, for example), it makes it easier to remove it all afterwards. But, in general, having declarations at global scope is simpler to deal with. After all, you might want to call that same function from somewhere else, too, and having the global declaration means you don't have to repeat it.

Using two namespaces only works partly

When I try to compile this code:
#include <iostream>
namespace Direction
{
enum Enum { UP, DOWN, LEFT, RIGHT };
}
using namespace std;
void move(int pDir);
int main()
{
printf("UP: %u\n", Direction::UP);
printf("DOWN: %u\n", Direction::DOWN);
printf("LEFT: %u\n", Direction::LEFT);
printf("RIGHT: %u\n", Direction::RIGHT);
move(Direction::UP);
return 0;
}
void move(int pDir)
{
printf("Move: ");
switch(pDir)
{
case(Direction::UP):
printf("UP");
break;
case(Direction::DOWN):
printf("DOWN");
break;
case(Direction::RIGHT):
printf("RIGHT");
break;
case(Direction::LEFT):
printf("LEFT");
break;
default:
printf("nothing");
break;
}
}
The result I expect would be:
UP: 0
DOWN: 1
LEFT: 2
RIGHT: 3
Move: UP
Instead the result is:
UP: 0
DOWN: 1
LEFT: 2
RIGHT: 3
It seems like void move(..) just gets ignored.
I already found the problem: It's the using namespace std. When I delete it, I get the result as expected.
So I have three questions:
1) Why does void move(..) just gets "ignored"
2) Why can I access the members of Direction within the first four lines of int main()
3) How can I fix this? ,_,
Have a nice day my friends.
ps: This is an extracted example of my problem, on my project I need to use the namespace std.
Your move function application has been reviewed and unfortunately, a
better application has been found. Please don't hesitate to reach us
for comments or questions.
std::move in utility header is the function being called in this situation. This is due to multiple factors :
The utility header is included by iostream, so it is defined in your code
Because of using namespace std, any function definition in the std namespace is now candidate for overload resolution in the global scope (see Namespace scope).
The argument Direction::UP is a rvalue, and the signature of std::move is template< class T >constexpr typename std::remove_reference<T>::type&& move( T&& t ) noexcept;. T can resolve to the enum type without conversion.
Yours is void move(int pDir); and will require an implicit conversion from Direction::Enum&& to int
When you remove on of these condition your function will be called. For instance
move((int)Direction::UP);
remove the need for an implicit conversion.
Due to your using namespace std both move (yours) and std::move are now accessible through the name move and when you call it, the usual overload resolution takes place, so the compiler checks whether
move(int)
or
template<typename T> move(T) // bit simplified here
is a better match for your call move(Direction::UP). Since the underlying type (aka std::underlying_type) of an unscoped enum is implementation defined, it may be a char or short (or anything else), in which case the second candidate is a better match.
Other factors (like the rvalue-ness mentioned by UmNyobe) and the namespace of the arguments can as well have an influence on overload resolution. Moving the definition of your move into the Direction namespace for example should lead to the first candidate being called, since ADL (argument dependent lookup) kicks in, although I am not 100% sure on that right now.
So my advice, as already suggested by the others, is to avoid using namespace as much as possible, at least at file scope. If you need to access a lot of stuff from one namespace, simply put the using namespace into the function that requires it. Regarding namespace std in particular, I highly recommend to never use using namespace std.

A couple of basic questions regarding "Hello World"

So I just started teaching myself C++ and I have two newbie questions regarding the Hello World exercise.
#include <iostream>
using namespace std; [1]
int main()
{
cout << "Hello, World" << endl; [2]
return 0;
}
[1] Is this line of code necessary? If not, why? It worked without it but I found a source that used it and was wondering why was this used.
[2] On my first try I forgot to add endl and the code worked. When I went to check I realised this was missing so why did it still work anyway?
Really basic questions but I want to understand the basics well.
Many thanks in advance.
Is this line of code necessary? If not, why? It worked without it but I found a source that used it and was wondering why was this used.
Namespace
First of all you should have to understand what a namespace is.
That's an argument reference:
Namespace.
Pratically a namespace is like a container. You can keep different
symbol's names. In that way, in very large project, it is possible define two different symbols (e.g two functions) with the same name.
I try to give you a little example:
I can define two different functions foo with the same name. It possibile because I put them inside two different namespaces.
namespace my_ns1 {
void foo(int a) {
return a;
}
}
namespace my_ns2 {
void foo(int a) {
return a + 2;
}
}
When I want to call the first foo function the proper invokation
will be:
my_ns1::foo(10); // return 10
If i want to call the second foo function, then:
my_ns2::foo(10); // return 12
In a specific block I can specify the intent to use always a namespace
with the code:
using namespace my_ns1;
In that way there is no more need to specify the "full name" of the function.
The standard library keeps all its function in a proper namespace: std.
So when you want to use a function in the standard library you have to invoke it with something like:
std::function(...)
If you use the code
using namespace std;
At the begin of your file, you're just saying to "open" that namespace
and you can call all function without std::
The namespace is usefull in order to prevent name conflict.
[2] On my first try I forgot to add endl and the code worked. When I went to check I realised this was missing so why did it still work anyway?
Simply
std::endl
is a proper way to insert the '\n' character which means "an end of line".

On an example of global inline functions in C++

Considering the following setup, I have ran into a quite strange phenomena, which I can not really explain. Using Visual Studio 2005, the following piece of code results in crash. I would like to really know the reason.
playground.cpp
static int local=-1;
#include "common.h"
int main(int arg)
{
setit();
docastorUpdate();
return 0;
}
common.h
#include <stdio.h>
#include <iostream>
void docastorUpdate();
static int *gemini;
inline void setit()
{
gemini = &local;
}
castor.cpp
static int local = 2;
#include "common.h"
void docastorUpdate() {
setit();
// crashing here, dereferencing a null pointer
std::cout << "castor:" << *gemini << std::endl;
}
The thing is, that the crash disappears when
I move the inline function setit() to an unnamed namespace
I make it static
To put it in a nutshell, I would need help to understand the reasons. Any suggestion is appreciated! (I am aware that, this solution is not one of the best partices, just being curious.)
This breaks because you are violating the one-definition rule. The one-definition rule says that in a program, across all translation units, there is only one definition of any given function. inline is sort of an exception to this rule, and it more or less means "dear compiler, there will be several definitions of this function, but they will all be the same, I promise".
static, when used here for local, means "dear compiler, this is an internal detail that only this translation unit will ever see; please do not confuse it with variables named local from other translation units"
So you promised the compiler that all definitions of setit will be the same, and asked the compiler to give each translation unit its very own local variable.
However, since the setit function uses whatever variable named local is in scope, the end result is two different definitions of setit, each one using a different variable. You just broke your promise. The compiler trusted you and the result was a totally messed up program. It thought it could do certain things with the code based on your promises, but since you broke them behind its back, those things it tried to do with the code didn't work at all.
Your code invokes undefined behaviour, in a very subtle way.
[C++11: 7.1.2/4]: An inline function shall be defined in every translation unit in which it is ODR-used and shall have exactly the same definition in every case. [..]
Although the definition looks the same because it's lexically copy-pasted into each translation unit by your #include, it's not because &local isn't taking the address of the same variable, in each case.
As a result, anything can happen when you run your program, including transferring all your hard-earned savings into my bank account, or taking away all of Jon Skeet's rep.
This is why making the function non-inline solves the problem; also, putting it in an unnamed namespace makes it a different function in each translation unit.
you can avoid using static in all the places, you can use extern in your case:
common.h:
extern int *gemini;
common.cpp;
int *gemini = nullptr;
also avoid using local like that , instead you can do this:
inline void setit(int * p)
{
gemini = p;
}
void docastorUpdate()
{
static int local = 2;
setit(&local);
std::cout << "castor:" << *gemini << std::endl;
}