Consider this example of two similar C++ member functions in a class C:
void C::function(Foo new_f) {
f = new_f;
}
and
void C::function(Foo new_f) {
this->f = new_f;
}
Are these functions compiled in the same manner? Are there any performance penalties for using this-> (more memory accesses or whatever)?
Yes, it's exactly the same and you'll get the same performance.
The only time you really must use the this-> syntax is when you have an argument to the function with the same name as an instance variable you want to access. Using the name of the variable by itself will refer to the argument so you need the this->. Of course, you could just rename the argument too. And, as ildjarn has pointed out in the comments also, you need to use this in certain situations to call functions that are dependent because this is implicitly dependent (you can read more about that though).
From the viewpoint of the compiler, there's no difference between this-> being implicit and being explicit.
Remember, however, that code should be written primarily for human readers, and only secondarily for the compiler. From this viewpoint, using this-> (except in the few places it's truly needed) is a huge loss, and should be expunged from all code.
It's a shorthand. In this case, it's exactly the same.
There is no performance penalty for the resulting code, because the compiler will have to use this to access the member anyway.
There is a performance penalty for me reading the code, because I would have to stop here and think "Why is this-> needed here? Is there a coding trick involved? Did I just miss something important about this class? Or did the coder just insert a random this-> for no reason?".
The compiler uses this pointer for you without you even knowing it. Whenever you type it yourself, you're explicitly stating it, but there's (in some cases) no need.
You can compare the assembly output of the two functions by compiling them under GCC with the flag -S. This will generate symbolic assembly code for the input C/C++ files, and the two should be identical.
Related
In C++ it is possible to declare that a function is const, which means, as far as I understand, that the compiler ensures the function does not modify the object. Is there something analogous in C++ where I can require that a function is pure? If not in C++, is there a language where one can make this requirement?
If this is not possible, why is it possible to require functions to be const but not require them to be pure? What makes these requirements different?
For clarity, by pure I want there to be no side effects and no use of variables other than those passed into the function. As a result there should be no file reading or system calls etc.
Here is a clearer definition of side effects:
No modification to files on the computer that the program is run on and no modification to variables with scope outside the function. No information is used to compute the function other than variables passed into it. Running the function should return the same thing every time it is run.
NOTE: I did some more research and encountered pure script
(Thanks for jarod42's comment)
Based on a quick read of the wikipedia article I am under the impression you can require functions be pure in pure script, however I am not completely sure.
Short answer: No. There is no equivalent keyword called pure that constrains a function like const does.
However, if you have a specific global variable you'd like to remain untouched, you do have the option of static type myVar. This will require that only functions in that file will be able to use it, and nothing outside of that file. That means any function outside that file will be constrained to leave it alone.
As to "side effects", I will break each of them down so you know what options you have:
No modification to files on the computer that the program is run on.
You can't constrain a function to do this that I'm aware. C++ just doesn't offer a way to constrain a function like this. You can, however, design a function to not modify any files, if you like.
No modification to variables with scope outside the function.
Globals are the only variables you can modify outside a function's scope that I'm aware of, besides anything passed by pointer or reference as a parameter. Globals have the option of being constant or static, which will keep you from modifying them, but, beyond that, there's really nothing you can do that I'm aware.
No information is used to compute the function other than variables passed into it.
Again, you can't constrain it to do so that I'm aware. However, you can design the function to work like this if you want.
Running the function should return the same thing every time it is run.
I'm not sure I understand why you want to constrain a function like this, but no. Not that I'm aware. Again, you can design it like this if you like, though.
As to why C++ doesn't offer an option like this? I'm guessing reusability. It appears that you have a specific list of things you don't want your function to do. However, the likelihood that a lot of other C++ users as a whole will need this particular set of constraints often is very small. Maybe they need one or two at a time, but not all at once. It doesn't seem like it would be worth the trouble to add it.
The same, however, cannot be said about const. const is used all the time, especially in parameter lists. This is to keep data from getting modified if it's passed by reference, or something. Thus, the compiler needs to know what functions modify the object. It uses const in the function declaration to keep track of this. Otherwise, it would have no way of knowing. However, with using const, it's quite simple. It can just constrain the object to only use functions that guarantee that it remains constant, or uses the const keyword in the declaration if the function.
Thus, const get's a lot of reuse.
Currently, C++ does not have a mechanism to ensure that a function has "no side effects and no use of variables other than those passed into the function." You can only force yourself to write pure functions, as mentioned by Jack Bashford. The compiler can't check this for you.
There is a proposal (N3744 Proposing [[pure]]). Here you can see that GCC and Clang already support __attribute__((pure)). Maybe it will be standardized in some form in the future revisions of C++.
In C++ it is possible to declare that a function is const, which means, as far as I understand, that the compiler ensures the function does not modify the object.
Not quite. The compiler will allow the object to be modified by (potentially ill-advised) use of const_cast. So the compiler only ensures that the function does not accidentally modify the object.
What makes these requirements [constant and pure] different?
They are different because one affects correct functionality while the other does not.
Suppose C is a container and you are iterating over its contents. At some point within the loop, perhaps you need to call a function that takes C as a parameter. If that function were to clear() the container, your loop will likely crash. Sure, you could build a loop that can handle that, but the point is that there are times when a caller needs assurance that the rug will not be pulled out from under it. Hence the ability to mark things const. If you pass C as a constant reference to a function, that function is promising to not modify C. This promise provides the needed assurance (even though, as I mentioned above, the promise can be broken).
I am not aware of a case where use of a non-pure function could similarly cause a program to crash. If there is no use for something, why complicate the language with it? If you can come up with a good use-case, maybe it is something to consider for a future revision of the language.
(Knowing that a function is pure could help a compiler optimize code. As far as I know, it's been left up to each compiler to define how to flag that, as it does not affect functionality.)
Does anyone know of any warnings that C++ compilers provide that help to enforce const correctness? For instance, it would be nice to have a warning produced by any C++ method that contains a non-const parameter that is never modified inside of the method. I see that there is a gnu compiler warning called -Wsuggest-attribute=const; however, when I use this flag I get an error saying that it is not recognized. Any ideas why?
I don't think such a warning exists, mostly because it would be useless. Just because a parameter is not modified inside the call, doesn't mean it should be made const just for the sake of it.
Think of virtual functions. Perhaps the designer of the base class, although not modifying the parameter in the base class, wants to leave it up to an extending class whether or not to modify that parameter.
Also, think of large applications, where modifying interfaces or API's or whatever costs a lot. You might not need to modify the parameter now, but intend to do so in the future. You're not going to make it const now, and force a full rebuild and probably risk errors in the future when you remove the const.
-Wsuggest-attribute=const
This analysis requires option
-fipa-pure-const
which is enabled by default at
-O
and higher
Careful, a const parameter like this one:
void myFunc(int const param);
does not belong to the interface. It belongs to the local scope of the function implementation. In fact, this function:
int inc(int const param) { return param+1; }
may be declared as
int inc(int param);
It is not a violation of the const correctness paradigm to claim the right to modify a variable but not actually do it.
If you are worried about const_cast you can either not use it in the first place or simply grep for it in your code base.
No, unfortunately there are no such warnings. You just get errors if you try to change const declared parameters. This is because missing const declarations do not change the correctness of the code from the compilers point of view. But const correctness is important for the compiler to discover potential optimizations and it improves the readability of the code. It is a matter of professionalism. Especially when using references const correctness is a must. I often refer to this.
The compiler itself takes const correctness very serious when operators (assignement, conversion, ...) come into play. A missing const here and the compiler refuses to use the operator because it makes a big difference if the given parameter may possibly be modified or not.
I'm not aware of such warnings and I think they would be rather hard to implement in a compiler - that is, they would slow it down. Maybe some static analysis tools have such features (but I'm not aware of those either).
As per Wsuggest-attribute=const, that is a different thing. It will suggest to use a gcc-specific "function attribute const", which is, basically, a mathematical function, receiving only values (no pointers), not reading or changing any static/global state and returning only a value (no pointers). For further description, look here: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
We obviously can't make everything constexpr. And if we don't make anything constexpr, well, there won't be any big problems. Lots of code have been written without it so far.
But is it a good idea to slap constexpr in anything that can possibly have it? Is there any potential problem with this?
It won't bother the compiler. The compiler will (or should anyway) give you a diagnostic when/if you use it on code that doesn't fit the requirements of a constexpr.
At the same time, I'd be a bit hesitant to just slap it on there because you could. Even though it doesn't/won't bother the compiler, your primary audience is other people reading the code. At least IMO, you should use constexpr to convey a fairly specific meaning to them, and just slapping it on other expressions because you can will be misleading. I think it would be fair for a reader to wonder what was going on with a function that's marked as a constexpr, but only used as a normal run-time function.
At the same time, if you have a function that you honestly expect to use at compile time, and you just haven't used it that way yet, marking it as constexpr might make considerably more sense.
Why I don't bother to try and put constexpr at every opportunity in list form, and in no particular order:
I don't write one-liner functions that often
when I write a one-liner it usually delegates to a non-constexpr function (e.g. std::get has come up several times recently)
the types they operate on aren't always literal types; yes, references are literal types, but if the referred type is not literal itself I can't really have any instance at compile-time anyway
the type they return aren't always literal
they simply are not all useful or even meaningful at compile-time in terms of their semantics
I like separating implementation from declaration
Constexpr functions have so many restrictions that they are a niche for special use only. Not an optimization, or a desirable super-set of functions in general. When I do write one, it's often because a metafunction or a regular function alone wouldn't have cut it and I have a special mindset for it. Constexpr functions don't taste like other functions.
I don't have a particular opinion or advice on constexpr constructors because I'm not sure I can fully wrap my mind around them and user-defined literals aren't yet available.
I tend to agree with Scott Meyers on this (as for most things): "Use constexpr whenever possible" (from Item 15 of Effective Modern C++), particularly if you are providing an API for others to use. It can be really disappointing when you wish to perform a compile-time initialization using a function, but can't because the library did not declare it constexpr. Furthermore, all classes and functions are part of an API, whether used by the world or just your team. So use it whenever you can, to widen its scope of usage.
// Free cup of coffee to the API author, for using constexpr
// on Rect3 ctor, Point3 ctor, and Point3::operator*
constexpr Rect3 IdealSensorBounds = Rect3(Point3::Zero, MaxSensorRange * 0.8);
That said, constexpr is part of the interface, so if the interface does not naturally fit something that can be constexpr, don't commit to it, lest you have to break the API later. That is, don't commit constexpr to the interface just because the current, only implementation can handle it.
Yes. I believe putting such constness is always a good practice wherever you can. For example in your class if a given method is not modifying any member then you always tend to put a const keyword in the end.
Apart from the language aspect, mentioning constness is also a good indication to the future programmer / reviewer that the expression is having const-ness within that region. It relates to good coding practice and adds to readability also. e.g. (from #Luc)
constexpr int& f(int& i) { return get(i); }
Now putting constexpr suggests that get() must also be a constexpr.
I don't see any problem or implication due constexpr.
Edit: There is an added advantage of constexpr is that you can use them as template argument in some situations.
I hope this isn't a duplicate of a question itself, but the search terms are so ambiguous, I can't think of anything better.
Say we have two classes:
class FloatRect
{
float x,y,width,height;
};
and somewhere else
class FloatBox
{
float top,left,bottom,right;
};
From a practical standpoint, they're the same, so does the compiler treat them both as some sort of typedef?
Or will it produce two separate units of code?
I'm curious because I'd like to go beyond typedefs and make a few variants of a type to improve readability.
I don't want needless duplication, though...
This is completely implementation specific.
For example I can use CLang / LLVM to illustrate both point of view at once:
CLang is the C++ front-end, it uses two distinct types to resolve function calls etc... and treats them as completely different values
LLVM is the optimizer backend, it doesn't care (yet) about names, but only structural representation, and will therefore collapse them in a single type... or even entirely remove the time definition if useless.
If the question is about: does introducing a similarly laid-out class creates overhead, then the answer is no, so write the classes that you need.
Note: the same happens for functions, ie the optimizer can merge blocks of functions that are identical to get tighter code, this is not a reason to copy/paste though
They are totally unrelated classes with regards to the compiler.
If they are just POD C-structs, it won't actually generate any real code for them as such. (Yes there is a silent assignment operator and some other functions but I doubt there will be code actually compiled to do it, it will just inline them if they are used).
Since the classes you use as samples are only relevant during compilation, there's nothing to duplicate or collapse. Runtime, the member variables are simply accessed as "the value at at offset N".
This is, of course, hugely implementation-specific.
Any internal collapse here would be completely internal to the mechanism of the compiler, and would not have an effect on the produced translated code.
I would imagine it's very unlikely that this is the case, as I can think of no benefit and several ways in which this would really complicate matters. I can't present any evidence, though.
No. As they are literally two different types.
The compiler must treat them that way.
There is no magic merging going on.
No they are not treated as typedefs, because they are different types and can for example be used for overloading functions.
On the other hand, the types have no code in them so there will be nothing to duplicate.
Any function that consists of a return statement only could be declared
constexpr and thus will allow to be evaluated at compile time if all
arguments are constexpr and only constexpr functions are called in its body. Is there any reason not to declare any such function constexpr ?
Example:
constexpr int sum(int x, int y) { return x + y; }
constexpr i = 10;
static_assert(sum(i, 13) == 23, "sum correct");
Could anyone provide an example where declaring a function constexpr
would do any harm?
Some initial thoughts:
Even if there should be no good reason for ever declaring a function
not constexpr I could imagine that the constexpr keyword has a
transitional role: its absence in code that does not need compile-time
evaluations would allow compilers that do not implement compile-time
evaluations still to compile that code (but to fail reliably on code
that needs them as made explict by using constexpr).
But what I do not understand: if there should be no good reason for
ever declaring a function not constexpr, why is not every function
in the standard library declared constexpr? (You cannot argue
that it is not done yet because there was not sufficient time yet to
do it, because doing it for all is a no-brainer -- contrary to deciding for every single function if to make it constexpr or not.)
--- I am aware that N2976
deliberately not requires cstrs for many standard library types such
as the containers as this would be too limitating for possible
implementations. Lets exclude them from the argument and just wonder:
once a type in the standard library actually has a constexpr cstr, why is not every function operating on it declared constexpr?
In most cases you also cannot argue that you may prefer not to declare a function constexpr simply because you do not envisage any compile-time usage: because if others evtl. will use your code, they may see such a use that you do not. (But granted for type trait types and stuff alike, of course.)
So I guess there must be a good reason and a good example for deliberately not declaring a function constexpr?
(with "every function" I always mean: every function that meets the
requirements for being constexpr, i.e., is defined as a single
return statement, takes only arguments of types with constexpr
cstrs and calls only constexpr functions. Since C++14, much more is allowed in the body of such function: e.g., C++14 constexpr functions may use local variables and loops, so an even wider class of functions could be declared constexpr.)
The question Why does std::forward discard constexpr-ness? is a special case of this one.
Functions can only be declared constexpr if they obey the rules for constexpr --- no dynamic casts, no memory allocation, no calls to non-constexpr functions, etc.
Declaring a function in the standard library as constexpr requires that ALL implementations obey those rules.
Firstly, this requires checking for each function that it can be implemented as constexpr, which is a long job.
Secondly, this is a big constraint on the implementations, and will outlaw many debugging implementations. It is therefore only worth it if the benefits outweigh the costs, or the requirements are sufficiently tight that the implementation pretty much has to obey the constexpr rules anyway. Making this evaluation for each function is again a long job.
I think what you're referring to is called partial evaluation. What you're touching on is that some programs can be split into two parts - a piece that requires runtime information, and a piece that can be done without any runtime information - and that in theory you could just fully evaluate the part of the program that doesn't need any runtime information before you even start running the program. There are some programming languages that do this. For example, the D programming language has an interpreter built into the compiler that lets you execute code at compile-time, provided that it meets certain restrictions.
There are a few main challenges in getting partial evaluation working. First, it dramatically complicates the logic of the compiler because the compiler will need to have the ability to simulate all of the operations that you could put into an executable program at compile-time. This, in the worst case, requires you to have a full interpreter inside of the compiler, making a difficult problem (writing a good C++ compiler) and making it orders of magnitude harder to do.
I believe that the reason for the current specification about constexpr is simply to limit the complexity of compilers. The cases it's limited to are fairly simple to check. There's no need to implement loops in the compiler (which could cause a whole other slew of problems, like what happens if you get an infinite loop inside the compiler). It also avoids the compiler potentially having to evaluate statements that could cause segfaults at runtime, such as following a bad pointer.
Another consideration to keep in mind is that some functions have side-effects, such as reading from cin or opening a network connection. Functions like these fundamentally can't be optimized at compile-time, since doing so would require knowledge only available at runtime.
To summarize, there's no theoretical reason you couldn't partially evaluate C++ programs at compile-time. In fact, people do this all the time. Optimizing compilers, for example, are essentially programs that try to do this as much as possible. Template metaprogramming is one instance where C++ programmers try to execute code inside the compiler, and it's possible to do some great things with templates partially because the rules for templates form a functional language, which the compiler has an easier time implementing. Moreover, if you think of the tradeoff between compiler author hours and programming hours, template metaprogramming shows that if you're okay making programmers bend over backwards to get what they want, you can build a pretty weak language (the template system) and keep the language complexity simple. (I say "weak" as in "not particularly expressive," not "weak" in the computability theory sense).
Hope this helps!
If the function has side effects, you would not want to mark it constexpr. Example
I can't get any unexpected results from that, actually it looks like gcc 4.5.1 just ignores constexpr