Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Why don't structs / classes collide with variables and functions when namespaces do?

How come namespaces, functions and variables all collide if they have the same name within the same scope, whereas structs / classes, while colliding with the first one, don't collide with variables and functions?

I could see why if structs / classes and namespaces collided with each other but not with functions and variables but I find it odd that structs / classes don't collide with variables and functions when namespaces do, perhaps because they are used in the same way (::) and both make out sorts of namespaces which would explain that they needed to be distinct from each other (whereas the result now seems a bit inconsequent).

Example 1:

int A;
struct A {};
//void A() {} //Collision with int A
//namespace A {} //Collision with int A (and also struct A if int A is removed)

Example 2:

struct A {};
void A() {} 
//int A; //Collision with function A
//namespace A {} //Collision with function A (and also struct A if int A is removed)

Example 3:

namespace A {}   
//struct A {}; //Collision with namespace A
//void A() {} //Collision with namespace A
//int A; //Collision with namespace A (and function A if namespace A is removed)
like image 258
fast-reflexes Avatar asked Oct 20 '14 22:10

fast-reflexes


1 Answers

I believe the reason why structs, as you say, don't "collide" with variables and functions is compatibility with C.

In C, a struct type has to be tagged with the struct keyword unless it's been typedefed. So you have things like struct stat and the stat function, both declared in <sys/stat.h>. In C there's no problem with this, because when you type stat alone, it means the function, and when you type struct stat, it means the type; there's no collision.

But what's supposed to happen when you #include <sys/stat.h> in C++ then? It's going to try to declare both the struct and the function in the global scope, with the same name, and in C++ you don't need the keyword struct when referring to a type. C++ must allow this "collision", otherwise it simply won't be possible to include such a header a C++ program. Furthermore, C++ must have the rule that when a function and a struct type declared in the same scope have the same name, that name alone means the function, whereas preceding it with struct names the type. Only then will compatibility with C be preserved.

For classes, it's presumably just because classes are supposed to be identical to structs except for default visibility of members and bases. It would unnecessarily complicate the language to introduce more differences.

There's no good reason to allow namespaces to have the same names as variables and functions in the same scope, since there are no namespaces in C. So it's not allowed.

like image 110
Brian Bi Avatar answered Nov 15 '22 00:11

Brian Bi