VS2013 is having trouble with base class being in unnamed namespace - c++

The following code compiles fine and runs as expected:
#include <iostream>
namespace
{
struct Base
{
void print() const { std::cout << "test"; };
};
};
class Derived : public Base
{
};
int main()
{
Derived d;
d.print();
return 0;
}
But when looking at d during runtime using QuickWatch, IntelliSense seems to be unable to find
Base.
I solved this by putting Base in a named namespace instead of an unnamed.
So is it a bug in Visual Studio, or am I missing something out?

This problem with anonymous namepaces has been an issue in VC++ for a while - see http://msdn.microsoft.com/en-us/library/0888kc6a%28VS.80%29.aspx. From the linked doc:
The native C++ expression evaluator does not support anonymous namespaces.
and
The only way to watch the symbol test in this example is to use the decorated name:
e.g. (int*)?test#?A0xccd06570#mars##3HA (using the namespace hierarchy given in the example to illustrate the point). Just use the decorated name? That's so convenient! Thanks, Microsoft.

Related

How does this name resolution work with an implementator function and a fallback function?

A project I'm working on requires multiple targets to be compiled for. Per target the underlying implementation may vary as the device requires hardware to be configured differently.
In order to force target implementations to follow a interface/design contract system was designed. If a target does not implement said interface accordingly, an error will be thrown upon usage.
The following code is tested using gcc, arm-none-eabi-gcc and clang
namespace A {
namespace C {
void foo() {}
}
}
namespace B {
using namespace A::C;
void foo() {}
}
using namespace A;
namespace C {
}
int main() {
B::foo(); // ok
C::foo(); // won't compile
return 0;
}
Now there are multiple questions that arise when reasoning why this code would compile or not:
Why does the compiler not report unresolved ambiguity between A::foo(bool) and B::set(bool)?
Why does C::foo() not compile, since my theory is that the same naming structure is achieved but on a different manner:
Why does the compiler not report unresolved ambiguity between target::set(bool) and interface_contracts::set(bool)?
In the first code snippet, name hwstl::target::pin::set hides name hwstl::interface_contracts::pin::set.
For the call hwstl::device::pin::set(true);, name lookup stops upon finding hwstl::target::pin::set. Only one candidate function, no ambiguity.
For the call hwstl::unsatisfied_device::pin::set(true);, there is only one function called set which can be found anyway.
10.3.4.1 A using-directive does not add any members to the declarative region in which it appears.
Why does the following code not compile?
In the second code snippet, you call set by qualified id: hwstl::unsatisfied_device::pin::set, compiler will only try to find name inside namespace hwstl::unsatisfied_device::pin. Thus it failed in finding the name introduced by the using directive using namespace interface_contracts; outside it.
Here is a simplified version of your code:
namespace A {
void foo() {}
}
namespace B {
using namespace A;
void foo() {}
}
using namespace A;
namespace C {
}
int main() {
B::foo(); // ok
C::foo(); // won't compile
return 0;
}

Visual studio unable to resolve overloaded unambiguous function in class and namespace

See code below
#include <iostream>
#include <string>
namespace stringhelper
{
std::string to_string(int n) { return "0"; } // ignore wrong implementation. simplified for example purpose
}
using stringhelper::to_string;
class TestClass
{
public:
std::string to_string() const { return "TestClass:" + to_string(m_value); }
private:
int m_value;
};
int main()
{
TestClass tc;
std::cout << tc.to_string();
}
If TestClass does not implement function to_string(), within TestClass, it is able to resolve to_string(m_value) to stringhelper::to_string(int). However, the moment TestClass implements function to_string(), the compiler is unable to resolve to_string(int) to stringhelper::to_string.
Rather, it insists/resolves the function to TestClass::to_string and gave an error that the function TestClass::to_string does not take in 1 arguments.
Why is this so?
Environment:
Visual Studio 2008 Professional Edition 9.0.21022.8 RTM
Configuration: Win32
Windows 8
This behavior is not limited to Visual Studio 2008. If tested in modern Clang implementations you will see the same behaviour. As you may know, functions in derived classes which don't override functions in base classes but which have the same name will hide other functions of the same name in the base class.
The "problem" here is that you, by using the using statement introduces a function named to_string into a scope that is essentially a victim of the exact same thing as what happens in the above example, when looking at it from inside your class.
If the standard had you call member functions with this->foo() this would probably not have been an issue. But since function calls within a class are presumed to be part of the class and only if not found looked for in other scopes this becomes an issue.
Since you have an implementation in your class, that has priority and will be used. Since you want a version that takes an int as an argument, an overloaded version of your member function will be looked for and since it does not exist you get the error you see.
This is part of why using namespace can often introduce errors that might be unintuitive to understand. If you want to make sure you use the stringhelper::to_string implementation while you are in a class with a function that has the same name you have to be explicit.
This would work fine for instance, even if you keep your using statement.
#include <iostream>
#include <string>
namespace stringhelper
{
std::string to_string(int n) { return "0"; } // ignore wrong implementation. simplified for example purpose
}
using stringhelper::to_string;
class TestClass
{
public:
std::string to_string() const { return "TestClass:" + stringhelper::to_string(m_value); }
private:
int m_value;
};
int main()
{
TestClass tc;
std::cout << tc.to_string();
}

How to use a struct defined in C++ CLR in unmanaged C++?

I have a struct defined in Managed.h and I would like to be able to use it inside a different project, which is unmanaged C++ (let's call it Unmanaged.h).
I tried referencing the dll, a few different #includes, but I couldn't make it work. Is there a simple way to do this ?
For information : I am quite new to C++ programming (I do C# usually), and I use Visual Studio 2015.
It would be useful to see some code and the error message that you are seeing. But as a basic example:
CLR file containing the struct. Call it MyStruct.h:
using namespace System;
namespace ManagedNameSpace {
public value struct MyStruct {
void f() {
System::Console::WriteLine("test");
}
};
}
The unmanaged class includes the CLR struct and as an explicit example I have called the object in the constructor but you can easily move this to an implementation file (Remember to include the file in the header):
#include "MyStruct.h"
class UnManagedClass {
public:
explicit UnManagedClass() {
ManagedNameSpace::MyStruct clrObj;
clrObj.f();
std::cout << "This compiles fine";
}
};
Take note that certain CLR types require marshalling. For example String will need to be marshalled. Here is an example of converting a string to LPCWSTR
LPCWSTR lpcwStr = (LPCWSTR)(Marshal::StringToHGlobalUni(clrString)).ToPointer()

Namespace name in c++

I am trying to create a namespace in c++ in the following way:
namespace MyCompany.Library.Myproduct {
public ref class ClassWrapper
{
};
}
I am getting error:
Error 1 error C2059: syntax error : '.' ClassWrapper.h 7 1 MyCompany.Library.Myproduct
Why can not I have . in namespace?
Edit1
This namespace definition is in a c++/cli and would be used in c# code. in C# this namespace is valid, but it seems it is not valid in c++. How can define c# compatible namespaces in c++/cli code?
You're not allowed to use the dot in namespace name. However, you can have nested namespaces.
namespace Boap
{
namespace Lib
{
namespace Prod
{
class Llama
{
public:
Llama()
{
std::cout << "hi" << std::endl;
}
};
}
}
};
And instanciate your llama this way:
Boap::Lib::Prod::Llama l;
AFAIK namespace and classname follow the same namming rules than variables.
A variable's name cannot start with a numeric character, and the same apply to class / namespace's names. The same goes for ".".
EDIT: The following is pure assumptions, because I have no knowledge of C# or windows CLI.
Does it make sense that a nested namespace in C++ (eg Boap::Lib) would be translated into Boap.Lib in C#? Maybe it's just as simple as that.
Now, in 2023 it is possible to achieve what you want; with ::. You need to make sure the C++ Language Standard is set to at least C++17.
Then this code would compile and work:
namespace MyCompany::Library::Myproduct {
public class ClassWrapper
{
};
}

C++ Multiple classes with same name

Say I have two different cpp files. Both declare classes with the same name, but perhaps a totally different structure (or perhaps the same structure, different implementation). The classes do not appear in the header files. (As an example, suppose they are Node classes for different list classes.)
I've seen these classes conflict. Is this expected by the standard? What solutions are there to this problem?
UPDATE:
As suggested by answers/comments, anonymous namespaces are what I was looking for.
The standard way around this problem is to wrap the classes in different namespaces.
It violates One Definition Rule. It's hard for compiler to detect the error, because they are in different compilation units. And even linker cannot detect all errors.
See an example in http://www.cplusplus.com/forum/general/32010/ . My compiler and linker (g++ 4.2.1) can build the final executable without any error, but the output is wrong.
If I change the example a bit, I get segmentation fault.
// main.cpp
#include <iostream>
#include <list>
using namespace std;
struct Handler
{
Handler() : d(10, 1.234) {}
list<double> d;
};
extern void test_func();
int main(void)
{
Handler h;
cout << h.d.back() << endl;
test_func();
return 0;
}
// test.cpp
#include <iostream>
#include <string>
using namespace std;
struct Handler
{
Handler() : d("test Handler") {}
string d;
};
void test_func()
{
Handler h;
cout << h.d << endl;
}
It's recommended to differentiate you class by namespace. For example of Node, you can use nest class and define the Node in the parent list class. Or you can add you class in anonymous namespace. See How can a type that is used only in one compilation unit, violate the One Definition Rule?
I'm not sure if I'm missing some detail here, but you wrap each class in a namespace.
namespace A {
class Node { };
}
namespace B {
class Node { };
}
Then you can use A::Node or B::Node.
You can use namespace to have multiple classes with same name by sub-scoping them in different namespaces. See: http://www.cplusplus.com/doc/tutorial/namespaces/
I've seen these classes conflict. Is this expected by the standard?
The standard says you can't do that. It would violate the one definition rule. (How to fix this has already been covered in other answers)