How is this possible to use in c++? - c++

To my surprise, I found that the name of a c++ object can be the same as class name. Can someone explain to me the reason why?
When I declare an object of class a as a a1(), it does not raise an error, but doesn't call the constructor. Why is this happening?
My code:
#include<iostream>
using namespace std;
class a
{
public:
a()
{
cout << "in a\n";
}
};
int main()
{
a a1();
a a;
}

When you write a a1(); it is actually being parsed as a function declaration not a call to the default constructor.
a a1;
will call the default constructor correctly
When you write a a; it works because the variable name takes preference over the class name in what is called name hiding, but even though it works it will only lead to confusion and I would avoid doing it.
And for all those people who like standards quotes here you go
A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.

a a1(); is a function declaration.
That's an important reason for the creation of uniform initialization in C++11. To initialize the object using the constructor in C++11, use a a1{};

It is valid to hide the name of a class with a variable in fact if you look at the C++draft standard section 3.3.10 Name hiding paragraph 2 says(emphasis mine):
A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is
visible.
I don't think it is good practice and it would lead to hard to maintain code. This line of code is actually declaring a function:
a a1();
you can alternatively use this pre-C++11:
a a1 ;
or uniform initialization introduced in C++11 :
a a1{} ;
Circling back to name hiding, I was pleasantly surprised to see that clang will warn you about this with this code regardless of the warning levels set:
int main()
{
a a;
a a2 ;
}
I receive this message:
main.cpp:12:10: note: class 'a' is hidden by a non-type declaration of 'a' here
a a;
^
although I can't see to obtain a similar warning from gcc.
Update
Thinking about this comments I made earlier on warts of uniform initialization, I realized that had you suspected that a1 was somehow not the correct type you could have have used typeid to debug what was going on. For example this code:
std::cout << typeid(a).name() << std::endl ;
std::cout << typeid(a1).name() << std::endl ;
results in this output on Coliru live example:
1a
F1avE
and passing it through c++filt you receive this output:
a () // A function that returns type a
a // type a

a a1(); is a function declaration return type as a which has nothing to do with the calling constructor
a a ; is simple statement works fine will call the constructor

This is what I got from your code when tried to compile it with clang, I think it says everything.
test.cpp:15:9: warning: empty parentheses interpreted as a function declaration
[-Wvexing-parse]
a a1();
^~
test.cpp:15:9: note: remove parentheses to declare a variable
a a1();
^~
1 warning generated.

Related

I do not understand why this compiles

I'm certainly missing something, but I do not understand why this compiles (with both g++ & clang++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
First of all, B is a type... not a value. How should I interpret this code?
It's interpreted as the declaration of a function named a, which takes one argument of type B and returns A.
It's simply a function declaration declaring a to be a function returning A and taking one unnamed parameter of type B.
It is valid because function declarations as opposed to function definitions are allowed within function definitions.
This issue is known as the most vexing parse. The line A a(B); can be interpreted as the declaration of a function named a returning an object of type A and taking an unnamed parameter of type B.
One way to avoid this issue is to use the uniform initialization syntax which was introduced in C++11, which consists in using braces instead of parenthesis: A a{B}; returns an error. The line is now interpreted as a variable declaration initialized with B, which is a type instead of a value.
Here's more information:
The Most Vexing Parse: How to Spot It and Fix It Quickly

Declare the same identifier as const variable and member function

I have wrote the following piece of code
#include <iostream>
const int N = 5;
class X
{
public:
int array[N];
void foo()
{
std::cout << "array size:"<<sizeof(array)/N << std::endl;
}
enum
{
N = 3
};
};
int main()
{
X x;
x.foo();
}
The aforementioned code does not compile with GCC:
<source>:13:8: error: declaration of 'N' [-fpermissive]
N = 3
^
<source>:2:11: error: changes meaning of 'N' from 'const int N' [-fpermissive]
const int N = 5;
^
From my point in compile time the array is defined as an array of five integers and N is defined as 5. How the compiler resolved the name declaration of variables?
Inside the scope of member functions (even those defined inline), the class is considered complete1. As such, using N there must use the member enumerator. And its value must be 3.
But, that is not the case when declaring class member data. At that point (when specifying array), the class is not made to be considered complete. So N can only refer to what was seen previously, which means it must be the global constant.
Clang accepts it, but emits 6 (sizeof(int) * 5 / 3). GCC (8) doesn't, but it isn't really invalid code. It's just error prone. The way to make better defined would be to move the enumerator to before the array is defined
enum { N = 3 };
int array[N];
... or if we don't, then we can use scope resolution to refer to the "correct N"
sizeof(array) / ::N
Rearranging the class definition would be better, since it will not still remain error prone (we can forget to use the qualified ::N).
1: From the latest C++ standard draft
[class.mem]/6
A complete-class context of a class is a
function body ([dcl.fct.def.general]),
default argument ([dcl.fct.default]),
noexcept-specifier,
contract condition ([dcl.attr.contract]), or
default member initializer
within the member-specification of the class.
In the line
int array[N];
N is the global N.
Inside the function foo(), the N is the one defined in the enum.
Inside the definition of foo() the definition of the class is used to resolve names. However, in the declaration of a member variable, only the declarations up to that line is used to resolve names.
If you change your class to
class X
{
public:
enum
{
N = 3
};
int array[N];
void foo()
{
std::cout << "array size:"<<sizeof(array)/N << std::endl;
}
};
Then, the N used to define array is the one defined in th enum.
PS
This is useful for understanding the language but, please, never ever use such coding style in real world applications.
The problem comes from the declaration int array[N];.
According to [basic.scope.class]/2:
A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.
In the context of the declaration, N is resolved to refer to ::N, but in the completed scope of X (all members are visible now), N is resolved to refer to the enumerator X::N, so the program is ill-formed; no diagnostic is required.

About Function Pointer in C++

Do these lines mean the same? Both works without any warning messages!
int (*pFunc)() = func1; // I learned this is right.
int (*pFunc)() = &func1; // Works well with an ampersand too.
Why do I have to put an ampersand in this case? Without it, doesn't work!
int (CMyClass::*pMemberFunc)() = &CMyClass::memberFunc1;
Why do I have to specify namespace for functions in Classes even if the type of the function pointer matches exactly?
int (*pMemberFunc)() = CMyClass::memberFunc1; // Compiler error
int (*pMemberFunc)() = &CMyClass::memberFunc1; // Compiler error
Why can't I specify namespace in this case?
namespace myNamespace {
int func1() {}
}
int (myNamespace::*pFunc)() = myNamespace::func1; // Compiler error
int (myNamespace::*pFunc)() = &myNamespace::func1; // Compiler error
int (*pFunc)() = &myNamespace::func1; // Works!
Your first question, legalese of the Standard:
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed
in parentheses. [Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in
parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because
there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to
member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is
&unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. —end note ]
While it seems inconsistent at first, I do like the fact that it makes the semantics for pointers to members (be them functions or not) equivalent. This certainly has benefits when dealing with templates and decltype.
For the second question, you scope the pointer variable with CMyClass because yours is not a simple "() -> int" function: memberFunc1() is implicitly passed a CmyClass* argument you normally refer to as "this".
If you could truly pass nothing, you'd be missing information (and possibly crash) for the method to do its job correctly. If you're accustomed to "delegates" in other languages, do remember these can optionally store a "Target" pointer to the "this" object if the method is not static/global.
As for the third, it's a free standing function, so it's truly () -> int, but you're attempting to scope your pointer to the namespace, when in fact you're not declaring your variable inside the namespace block.
While the namespace certainly alters how symbols are searched for, it doesn't affect the convention call of the function at all.
1) about Q1, looking at the following code, as the func1 is a right-value of the function, so with or without "&" doesn't change the actual function address.
Look at the following code:
#include <stdio.h>
void foo(){
printf("foo called\n");
}
int main(){
printf("%p\n", foo);
printf("%p\n", &foo);
void (*FUNC) ();
FUNC = foo;
FUNC();
printf("address %p\n", FUNC);
printf("address %p\n", &FUNC);
return 0;
}
output is
0x101406eb0
0x101406eb0
foo called
address 0x101406eb0
address 0x7fff5e7f9a80
Q2 & Q3 )
Pointers to Member Functions Are Not Pointers
You can refer it here
https://www.safaribooksonline.com/library/view/c-common-knowledge/0321321928/ch16.html

typecast operator in private base

I found something I consider strange behaviour in C++: a typecast operator in a private base class is confusing the compiler when trying to resolve an implicit cast:
#include <iostream>
struct Base
{
#ifdef ENABLE
operator bool () const { return true; }
#endif
};
struct Derived : private Base
{
operator int () const { return 7; }
};
int main()
{
Derived o;
std::cout << o << '\n';
return 0;
}
Without -DENABLE, the code compiles just fine, and outputs 7. With -DENABLE, the code no longer compiles, complaining about an ambiguous overload. I tried gcc-4.6.5, gcc-4.8.1, and clang-3.3. What's confusing is that I clearly cannot ask for (bool)o, because Base is a private base.
Is this expected behaviour?
Access control always comes last. Quote from the Standard:
10.2 Member name lookup [class.member.lookup]
1 Member name lookup determines the meaning of a name (id-expression)
in a class scope (3.3.7). Name lookup can result in an ambiguity, in
which case the program is ill-formed. For an id-expression, name
lookup begins in the class scope of this; for a qualified-id, name
lookup begins in the scope of the nestedname- specifier. Name lookup
takes place before access control (3.4, Clause 11).
8 If the name of an overloaded function is unambiguously found,
overloading resolution (13.3) also takes place before access control.
Ambiguities can often be resolved by qualifying a name with its class
name.
The reason both operators are considered is that a) the base clas conversion is not hidden by the derived one (which it would if both had been converting to the same type), b) both bool and int can be written to stdout, c) neither is a better match than the other so overload resolution yields an ambiguity. This yields a hard error even before access control comes into play.

Defining static const integer members in class definition

My understanding is that C++ allows static const members to be defined inside a class so long as it's an integer type.
Why, then, does the following code give me a linker error?
#include <algorithm>
#include <iostream>
class test
{
public:
static const int N = 10;
};
int main()
{
std::cout << test::N << "\n";
std::min(9, test::N);
}
The error I get is:
test.cpp:(.text+0x130): undefined reference to `test::N'
collect2: ld returned 1 exit status
Interestingly, if I comment out the call to std::min, the code compiles and links just fine (even though test::N is also referenced on the previous line).
Any idea as to what's going on?
My compiler is gcc 4.4 on Linux.
My understanding is that C++ allows static const members to be defined inside a class so long as it's an integer type.
You are sort of correct. You are allowed to initialize static const integrals in the class declaration but that is not a definition.
Interestingly, if I comment out the call to std::min, the code compiles and links just fine (even though test::N is also referenced on the previous line).
Any idea as to what's going on?
std::min takes its parameters by const reference. If it took them by value you'd not have this problem but since you need a reference you also need a definition.
Here's chapter/verse:
9.4.2/4 - If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.
See Chu's answer for a possible workaround.
Bjarne Stroustrup's example in his C++ FAQ suggests you are correct, and only need a definition if you take the address.
class AE {
// ...
public:
static const int c6 = 7;
static const int c7 = 31;
};
const int AE::c7; // definition
int f()
{
const int* p1 = &AE::c6; // error: c6 not an lvalue
const int* p2 = &AE::c7; // ok
// ...
}
He says "You can take the address of a static member if (and only if) it has an out-of-class definition". Which suggests it would work otherwise. Maybe your min function invokes addresses somehow behind the scenes.
Another way to do this, for integer types anyway, is to define constants as enums in the class:
class test
{
public:
enum { N = 10 };
};
Not just int's. But you can't define the value in the class declaration. If you have:
class classname
{
public:
static int const N;
}
in the .h file then you must have:
int const classname::N = 10;
in the .cpp file.
Here's another way to work around the problem:
std::min(9, int(test::N));
(I think Crazy Eddie's answer correctly describes why the problem exists.)
As of C++11 you can use:
static constexpr int N = 10;
This theoretically still requires you to define the constant in a .cpp file, but as long as you don't take the address of N it is very unlikely that any compiler implementation will produce an error ;).
C++ allows static const members to be defined inside a class
Nope, 3.1 §2 says:
A declaration is a definition unless it declares a function without specifying the function's body (8.4), it contains the extern specifier (7.1.1) or a linkage-specification (7.5) and neither an initializer nor a functionbody, it declares a static data member in a class definition (9.4), it is a class name declaration (9.1), it is an opaque-enum-declaration (7.2), or it is a typedef declaration (7.1.3), a using-declaration (7.3.3), or a using-directive (7.3.4).