In the Clang AST how to know if a DeclRefExpr in a method refers to a local or a non-static data member of the struct/class containing the method? - c++

In the Clang AST how to know if a DeclRefExpr in a method refers to a local or a non-static data member of the struct/class containing the method?
That is, if I were translating the C++ to C and I were explicitly inserting the 'this' parameter and I wanted to explicitly prefix all references to the members of the 'this' class by translating 'x' into 'this->x', how do I know for which DeclRefExprs to do this?

it seems that we want to call NamedDecl::isCXXInstanceMember() on the output of DeclRefExpr::getDecl()
but the context in which I wanted to know this makes it moot: Clang seems to insert explicit MemberExpr and CXXThisExpr expressions when a non-static data member is accessed

Related

Does a constructor also have an implicit this parameter

I am learning about classes in C++ and know that non-static member functions have implicit this parameter. My first question is that does constructor also have an implicit this parameter just like non-static member functions. Note that i am not asking whether we can use this inside a ctor as i already know that we can use this inside a ctor.
Next, I know that inside a const qualified non-static member function for a class X, the type of this is const X*. And for a non-static member function(without const qualified), the type of this is X*. Similarly, inside the ctor the type of this is always X*. Here comes the deeper question.
We know that when we call a non-static member function(say like obj.func()), then the address of the object named obj is implicitly passed to the implicit this parameter of the method func. So this explains "where the this comes from in case of non-static member function".
Now, lets apply the same thing to constructors. For example, say we create an object of class X using default ctor like:
X x; //does the default ctor also have an implicit this parameter to which the address of x is passed?
My second question is: Does the same thing happen to ctors? Like, the address of x is passed to an implicit parameter of the default ctor. My current understanding is that ctors don't have an implicit this parameter. So when we write X x;, the address of x is not passed as an argument because the object is not created yet and so it doesn't make sense to pass its address. But from the standard we know that inside a ctor we can use the this pointer. So my second question essentially is that, if ctors don't have an implicit this parameter then where does the this in the statement this->p = 0; come from? We know that before using any name(like variable name) in C++, we must have a declaration for that name. So where is the declaration for this? Does the compiler implicitly declares the this in case of ctor? I mean, in case of non-static member function, i can understand that they have the declaration for this as the implicit this parameter but what happens in ctors? How inside ctors we're able to use the name this without having a declaration for that?
struct Name
{
private:
int p = 0;
int k = 0;
void func() //func is a non-static member function and so have an implicit this parameter
{
this->k = 0; // the "this" here comes from implicit this parameter
}
Name()
{
this->p = 0; //where does the "this" comes from here since ctor don't have implicit this parameter
}
};
My third question is that is the concept of implicit this parameter an implementation detail or does the standard says that non-static member function will have an implicit this parameter.
Summary
Do ctors have an implicit this parameter? This first question can also be phrased as "Do ctors also have an implicit object parameter?".
The standard says that we can use this inside a ctor. But where does that this come from. For example, in case of a non-static member function, we know that this comes from the implicit this parameter, but in case of ctors, since ctors don't have an implicit this parameter, where does that this that we're allowed to use inside ctor come from.
Is the concept of implicit this parameter an implementation detail or does the standard say that all non-static member functions have an implicit this parameter, in which case, ctors are also allowed by implementations to have an implicit this parameter.
Edit:
The most important part(IMO) of this question is that how are we able to use the name this inside a ctor? For example when we write:
this->p = 0; //here "this" behaves like a name
In the above statement this behaves like a name. And we know that before using any name(like variable name) in C++, we must have a declaration for that name. So where is the declaration for this? Does the compiler implicitly declares the this in case of ctor? I mean, in case of non-static member function, i can understand that they have the declaration for this as the implicit this parameter but what happens in ctors? How inside ctors we're able to use the name this without having a declaration for that?
From the perspective of the C++ standard
The standard only describes the semantics of the this keyword and not how its value gets there. That's completely abstracted away and an implementation has great flexibility in making it happen.
From the perspective of theoretical computer science
The address of the object under construction, available via the this keyword, absolutely is an input to the initialization procedure (called "constructor" in C++) for the object. So are addresses of virtual base subobjects, which C++ also makes available via the this keyword but cannot be calculated from the main input, so any such must be additional inputs.
Note that CS tends to use "parameter" with procedures more in the sense of template parameters than dynamic variable inputs. And CS uses "function" to mean a procedure without side effects. A C++ constructor is not a CS "function" and while templated constructors are possible (parametric procedures) the value of this is an ordinary input not a parameterization.
Neither is a C++ constructor a method -- there is no polymorphic target-type-dependent dispatch, and so in particular the this input is not used for dispatch.
From the perspective of ABI rules for parameter-passing
A C++ constructor is a special member function. There's no way to construct a function pointer for it or invoke it C-style; ABI requirements for C functions do not apply.
If the platform ABI explicitly describes C++ behaviors, then there will be one or more rules for passing the value(s) of this to a C++ constructor. Those rules may or may not specify a mechanism equivalent to other function arguments, but every ABI-compliant C++ compiler targeting that platform will pass this values as required by the special rules for constructors.
Notably, the ABI for passing this to a constructor isn't required to be equivalent to how this is passed to other (non-special and non-static) member functions, although practical ABIs may well use the same approach for both.
There's no such thing as "implicit this parameter" in the standard. The standard calls it an "implicit object parameter".
An implicit object parameter is only relevant to overload resolution, it doesn't "become" this. Separately, this is defined to have the same cv qualification as the member function.
Do ctors have an implicit this parameter? This first question can also be phrased as "Do ctors also have an implicit object parameter?".
No, from [over.match.funcs]
For the purposes of overload resolution, both static and non-static member functions have an implicit object parameter, but constructors do not.
But where does that this come from.
The object being constructed.
Is the concept of implicit this parameter an implementation detail or does the standard say that all non-static member functions have an implicit this parameter, in which case, ctors are also allowed by implementations to have an implicit this parameter.
The implicit object parameter is part of the rules of overload resolution, it doesn't influence this.
How inside ctors we're able to use the name this without having a declaration for that?
this is not a name, it is a language keyword. The language defines this in a non-static member function to be a prvalue expression. Unlike an unqualified-id (that names an object) in the same position, which are glvalue expressions.
That's the language-lawyer answer. Having said that, I do find that "implicit object parameter becomes this" is a useful mental model.
Recall that constructors (and destructors) can't be cv qualified, so there isn't anything for it to distinguish in a constructor, so it doesn't matter if it exists or not.
"this" is a keyword; it doesn't need declaring, but is always available in non-static member functions.
See e.g. the draft standard here.
The keyword this names a pointer to the object for which an implicit object member function is invoked or a non-static data member's initializer is evaluated.
Note that the mechanism behind this is unspecified.

Deprecating static class members in C++11

I have come across different macros which enable deprecation of member attributes and functions but none of them discuss the possibility of deprecating static class members.
I read that even in C++14 deprecation of static members is not allowed.
Is there any specific reason for this?
Let's get some facts:
The wording for the [[deprecated]] attribute is the following
(based on N4269 7.6.5 [dcl.attr.deprecated], emphasis mine):
The attribute may be applied to the declaration of a class, a typedef-name, a variable, a non-static data
member, a function, a namespace, an enumeration, an enumerator, or a template specialization.
The misleading part is the explicit appearance of "non-static data members" without its counterpart at the same level in this list, but in that same list there are two other elements of interest.
The description of a variable is (based on 3 [basic]) :
A variable is introduced by the declaration of a reference other than a non-static data member or of an
object. The variable’s name, if any, denotes the reference or object.
Which means that saying a variable includes static data members
A static member function is a function (a red car is a car, this is a logical conclusion and i don't seem to find anything counter indicating this in the standard).
There isn't any syntax or behaviour problem applying particularly to static members, a static function is pretty much a free function in a namespace and static data member is more or less a global variable in a namespace and you can deprecate free functions and global variables..
As a bonus, it actually works in major compilers.
Summing up all this facts basically means that the [[deprecated]] attribute may actually be applied to a static data member, a non-static data member and a static member function, among other things.
So to answer your question, from my understanding, deprecating static members is actually allowed by the standard.

C++ : friends of class and "this" pointer

I have one little question for you :), I understand that every method "secretly" gets "this" pointer of some class that they are inside but why that wont happen to "friend" functions ?
Is it because they are NOT methods of class?
Can anyone explain whole machinery, i am very interested in how "this" really works!
thanks in advance! :)
friend functions and classes are just used for access control checked by the compiler.
friend functions are just standard functions, so there won't be any differences regarding calling conventions.
friend functions are not member of any class, so no this pointer is passed (as done with static member functions)
Non-static member function of a class will get a hidden this pointer (depending on the ABI this is often the first argument), static member functions don't get the this pointer because they don't act on instance data.
How exactly the this pointer is passed to a member function heavily depends on the used ABI, which depends on the architecture and operating system. Either it will be pushed on the stack, or it will be passed through a well known register.
Please consider reading "Where is the 'this' pointer stored in computer memory?".
"Friendship" and "Membership" are two different things. A function can be a member function or not, and independantly be a friend function or not.
You can declare a member function to be a friend function of another class, i.e.
class B{
friend void A::func(B);
//stuff
};
Here, the member function func from class A is declared as friend and can access B's private, and it will have a this pointer, that points to the object of class A on which func has been called.
The this pointer is an implicit parameter of non-static member functions, which is described in section 9.3.2 of the C++ Standard. How it is passed to the function depends on your compiler/architecture, i.e. it is implementation defined (so you might want to read your favorite compiler's documentation to learn about how it manages this pointers).

C++ proper usage, this pointer [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When should I make explicit use of the this pointer?
I'm wondering about the proper usage of the "this" pointer.
I've seen someone create a class constructor with the argument passed variable passed in named 'data'.
However he had a private member variable named 'data' already thus he simply used:
this->data = data;
would have worked to simply use
data = data_in
(if the parameter was named data_in), and no need to invoke the "this" pointer and reference the member type.
Now I'm wondering, is this proper usage? Using this->member to reduce on naming complexity? I mean it works and I see that it accomplishes what was intended but I'm wondering if some of you more experienced C++ guys and girls can say a word or two if this is common practice?
Also, out of curiosity I've instrumented the code just to see what happens under the hood, and it seems the "this" pointer is invoked anyhow. I guess that's the way references to the class object are done anyways.
In most cases, specifically dereferencing the this pointer to access a non-static data-member of the class instance is unnecessary, but it can help with naming confusion, especially when the data-members of the class are defined in a separate header file from the code-module. However, it is necessary to use the this pointer if you are accessing a non-static data-member that is a member of a base-class that is a templated class. In other words, in a situation like:
template<typename T>
class base_class
{
protected:
int a;
};
template<typename T>
class derived_class : public base_class<T>
{
void function()
{
a = 5; //this won't work
this->a = 5; //this will work
}
};
you'll note that you must use the this pointer in order to properly resolve the inherited non-static data-member from the template base-class. This is due to the fact that base_class<T>::a is a dependent name, in this case dependent on the template parameter T, but when used without the this pointer, it is treated as a non-dependent name, and is therefore not looked up in the dependent base-class namespace. Thus without the specific dereference of the this pointer, you'll end up with a compiler error like "a was not declared in this scope", or something similar.
No accessing a class member as:
this->member = something;
is same as accessing the member by itself,
member = something;
The compiler sees both as same and their is no overhead involved. Even if you use the second format the compiler does the same as first format under the hood.
In short, trying to use either of the two formats with aim of improving performance is useless. Ofcourse, You might have to use the first format in some template cases( accessing non-static data members of a templated Base class) but that is not for performance.
Essentially identical, except as Jason pointed out.
The nice part is that if you use this-> most editors will code complete for you, saving you typing.
It is "correct", but it is also poor practice. Naming parameters the same as class members is a bad idea. Intentionally creating naming conflicts is a bad idea.
Scoping operators are designed for when naming conflicts are unavoidable, such as when overriding a base member, or when using two libraries with identifier names chosen independently. Don't consider them free license for doing stupid things.
Unless you're practicing for an obfuscated code contest. Then by all means introduce naming collisions.

'static' for c++ class member functions?

Why is the static keyword necessary at all?
Why can't the compiler infer whether it's 'static' or not?
As follows:
Can I compile this function without access to non-static member data? Yes -> static funcion.
No -> non-static function.
Is there any reason this isn't inferred?
If you expect the compiler to decide on the spot whether it's static or not, how does that affect external source files linking against the header file that just defines the method signatures?
The propery of being static or non-static affects the function type. Non-static member functions have an implicit this parameter, while static ones don't, for one example.
In other words, there's a major qualitative difference between static and non-static member functions. The compiler cannot "infer" this. This is a matter of the author's intent.
If I want (and need) my function to be non-static, I make it non-static, even if it doesn't access any non-static members of the class. If the compiler suddently decides to make my non-static function static just because it doesn't access any non-static members of the class, in general case it will destroy the functionality of the code.
Yes the compiler could, but it has no knowledge of your intent. And the original designers probably thought that supplying your intent was important.
Having redundancy in like this in the language helps to insure that many programmer errors will end up being caught by the compiler.
Another reason: If the function is static, it can't be overridden in derived classes. No polymorphism.