In which cases will the restrict qualifier applied to a return value have an effect? - c++

If I have a member function declared like so:
double* restrict data(){
return m_data; // array member variable
}
can the restrict keyword do anything?
Apparently, with g++ (x86 architecture) it cannot, but are there other compilers/architectures where this type of construction makes sense, and would allow for optimized machine code generation?
I'm asking because the Blitz library (Blitz++) has a whole slew of functions declared in this manner, and it doesn't make sense that someone would go in and add the restrict keyword unless it actually does something. So before I go in and remove the restrict's (to get rid of compiler warnings) I'd like to know how I'm abusing the code.

WHAT restrict ARE WE TALKING ABOUT?
restrict is, as it currently stands, non-standard.. which means that it's a compiler extension; it's non-portable in the sense that the C++ Standard doesn't mandate its existance, nor is there any formal text in it that tells us what it is supposed to do.
restrict is currently compiler specific in C++, and one has to resort to the compiler documentation of their choice to see exactly what it is doing.
SOME THOUGHTS
There are many papers about the usage of restrict, among them:
Restricted Pointers - Using the GNU Compiler Collection
restrict - wikipedia.org
Demystifying The Restrict Keyword - CellPerformance
It's hinted at several places that the purpose of restrict is to qualify pointers so that the compiler knows that two pointers in the same scope doesn't refer to the same memory location.
With this in mind we can easily see that the return-type has no potential collision with other pointers, so using it in such context will generally not gain any optimization opportunities. However; one must refer to the documented behaviour of the used implementation to know for sure.. as stated: restrict is not standard, yet.
I also found the following thread where the developers of Blitz++ discusses the removal of strict applied to the return-type of a function, since it doesn't do anything:
Re: [Blitz-devel] type qualifiers ignored on function return type
A LITTLE NOTE
As a further note, here's what the LLVM Documentation says about noalias vs restrict:
For function return values, C99’s restrict is not meaningful, while LLVM’s noalias is.

Generaly restrict qualifier can only help to better optimize code. By removing 'restrict' you don't break anything, but when you add it without care you can get some errors. A great example is the difference between memcpy and memmove. You can always use slower memmove, but you can use faster memcpy only if you know that src and dst aren't overlaping.

Related

How to put inline functions in the C++ source file?

How can I force the inlining of a function, but define it in a C++ file ?
This is a question that's been asked in the past, for example here: Moving inline methods from a header file to a .cpp files
The answers there, in short, go as follows: "inline used to mean [remove function call overhead at the expense of .text size], now it means [relax ODR], so don't use inline for anything that's not ODR related, the compiler knows better".
I'm aware of that, however in my somewhat exotic case, I don't care about performance.
I'm programming an embedded device and, should someone break through the other layers of security, I want to make it as obnoxious as possible to reverse engineer this part of the code, and one thing this implies is that I don't want function calls (that aren't called numerous times anyway) to expose the function boundaries, which are natural delimitations of pieces of code that achieve something on their own.
However, I would also like to keep my code orderly and not have code in my header files.
I see that I can use __attribute((force_inline)) to force inlining, but then I get warnings if those functions don't have an inline attribute too: warning: always_inline function might not be inlinable [-Wattributes]
Suppressing the attributes warning is an option, but I'd rather only take it once I'm sure there are no clean way to do this.
Hence the question: how can I have a forcibly inlined function whose declaration is in a header, but definition is in a source file, without suppressing all attributes warnings ? Is that impossible ?
Inlining can only be asked. Sometimes a bit forcefully. But you can never guarantee that the function WILL be inlined finally - because reasons, sometimes quite obscure ones.
Here what's MSVC documentation says (I've highlighted the important parts):
The compiler treats the inline expansion options and keywords as suggestions. There's no guarantee that functions will be inlined. You can't force the compiler to inline a particular function, even with the __forceinline keyword. When compiling with /clr, the compiler won't inline a function if there are security attributes applied to the function.
C++ standard says:
No matter how you designate a function as inline, it is a request that the compiler is allowed to ignore: the compiler might inline-expand some, all, or none of the places where you call a function designated as inline.
GCC documentation is a bit less crystal-clear about non-inlinable functions, but cases exists anyway.
The only "real" way to force inlining is quite ugly, since it rely on inlining it before compilation... Yeah, old-style preprocessor macros. The Evil Itself. Or by using a dirty hack with a #include replacing the function call (and inserting C++ code instead)... It may be a bit safer than a macro, regarding double evaluations, but other side-effects can be even worse since it must rely on "global" variables to work.
Does it worth the pain? Probably not. In particular for "obfuscation", because it won't be as "secure" as you think it will be. Yes, an explicit function call is easier to trace. But it won't change anything: reverse engineering don't rely on that to be done. In fact, obfuscation is near never a good (or even working...) solution. I used to think that... a long, very long time ago. I proved to myself that it was near useless. On my own "secured" code. Breaking the code took me much less time than it took me to "protect" it...

Why is it not allowed to have default arguments on function declaration and definition?

so why is it not allowed to have default arguments on the function declaration and implementation? Wouldnt this be more readable for the implementer and the user of the function?
Is there a special reason why this is not allowed, or why the compiler or linker cant handle this?
Best regards
In fact, it is just that we cannot have, in the same scope, 2 declarations with a (common parameter with a) default argument:
void foo(int = 42);
void foo(int = 42); // Error.
and definition acts also as declaration.
if your definition doesn't include the header with the declaration,
you might have default in definition too.
Notice that default is not part of the signature, but should anyway is the same (by scope) for each translation unit (for inline functions, and also for non-inline functions since C++20 (but some default can be omitted)).
I don't know the why of those rules though.
There is no real reason except that the committee decided so and they apparently like to show their power by torturing millions of programmers this way.
Ok... may be this is not true but in my opinion it's a more logical explanation of why this is forbidden that anything I've read about the issue.
Note that g++ with -fpermissive allows default to be specified both in declaration and in implementation IF THE VALUES ARE THE SAME and gives an error if they are different.
This is the way IMO it should be in the standard, but it's not.
Because no.
PS: Don'y try to read too much into logical reasons about the rules of C++. Many times there are reasons, sometimes there are just poor justifications of a sad incident that must stay in forever for backward compatibility, sometimes there is no reason at all... it's just the way it is. This, added to the complexity of C++ and the concept of Undefined Behavior, is in my opinion why experimenting with C++ doesn't work well and you need to actually read the standard rules. Being smart doesn't help if you're experimenting, because the "correct" answer is often the wrong one. There's no way you can guess what was the decision taken in that rainy day at the committee meeting.

Micro optimization - compiler optimization when accesing recursive members

I'm interested in writing good code from the beginning instead of optimizing the code later. Sorry for not providing benchmark I don't have a working scenario at the moment. Thanks for your attention!
What are the performance gains of using FunctionY over FunctionX?
There is a lot of discussion on stackoverflow about this already but I'm in doubts in the case when accessing sub-members (recursive) as shown below. Will the compiler (say VS2008) optimize FunctionX into something like FunctionY?
void FunctionX(Obj * pObj)
{
pObj->MemberQ->MemberW->MemberA.function1();
pObj->MemberQ->MemberW->MemberA.function2();
pObj->MemberQ->MemberW->MemberB.function1();
pObj->MemberQ->MemberW->MemberB.function2();
..
pObj->MemberQ->MemberW->MemberZ.function1();
pObj->MemberQ->MemberW->MemberZ.function2();
}
void FunctionY(Obj * pObj)
{
W * localPtr = pObj->MemberQ->MemberW;
localPtr->MemberA.function1();
localPtr->MemberA.function2();
localPtr->MemberB.function1();
localPtr->MemberB.function2();
...
localPtr->MemberZ.function1();
localPtr->MemberZ.function2();
}
In case none of the member pointers are volatile or pointers to volatile and you don't have the operator -> overloaded for any members in a chain both functions are the same.
The optimization rule you suggested is widely known as Common Expression Elimination and is supported by vast majority of compilers for many decades.
In theory, you save on the extra pointer dereferences, HOWEVER, in the real world, the compiler will probably optimize it out for you, so it's a useless optimization.
This is why it's important to profile first, and then optimize later. The compiler is doing everything it can to help you, you might as well make sure you're not just doing something it's already doing.
if the compiler is good enough, it should translate functionX into something similar to functionY.
But you can have different result on different compiler and on the same compiler with different optimization flag.
Using a "dumb" compiler functionY should be faster, and IMHO it is more readable and faster to code. So stick with functionY
ps. you should take a look at some code style guide, normally member and function name should always start with a low-case letter

Is the register keyword still used?

Just came across the register keyword in C++ and I wondered as this seems a good idea (keeping certain variables in a register) surely the compiler does this by default?
So I wondered is this keyword still used?
Most implementations just ignore the register keyword (unless it imposes a syntactical or semantical error).
The standard also doesn't say that anything must be kept in a register; merely that it's a hint to the implementation that the variable is going to be used very often. Its use is even deprecated.
7.1.1 Storage class specifiers [dcl.stc]
3) A register specifier is a hint to the implementation that the variable so declared will be heavily used. [ Note: The hint can be ignored and in most implementations it will be ignored if the address of the variable is taken. This use is deprecated (see D.2). — end note ]
The standard says this (7.1.1(2-3)):
The register specifier shall be applied only to names of variables declared in a block (6.3) or to function parameters (8.4). It specifies that the named variable has automatic storage duration (3.7.3). A variable declared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default.
A register specifier is a hint to the implementation that the variable so declared will be heavily used. [ Note: The hint can be ignored and in most implementations it will be ignored if the address of the variable is taken. This use is deprecated (see D.2). — end note ]
In summary: register is useless, vestigial, atavistic and deprecated. Its main purpose is to make the life of people harder who are trying to implement self-registering classes and want to name the main function register(T *).
Probably the only remotely serious use for the register keyword left is a GCC extension that allows you to use a hard-coded hardware register without inline assembly:
register int* foo asm("a5");
This will mean that any access to foo will affect the CPU register a5.
This extension of course has little use outside of very low-level code.
Only specific number of registers are available for any C++ program.
Also, it is just a suggestion for the compiler mostly compilers can do this optimization themselves so there is not really much use of using register keyword and so more because compilers may or may not follow the suggestion.
So the only thing register keyword does with modern compilers is prevent you from using & to take the address of the variable.
Using the register keyword just prevents you from taking the address of the variable in C, while in C++ taking the address of the variable just makes the compiler ignore the register keyword.
Bottomline is, Just don't use it!
Nicely explained by Herb:
Keywords That Aren't (or, Comments by Another Name)
No, it's not used. It's only a hint, and a very weak one at that. Compilers have register allocators, they can figure out which variables should be kept in registers (and account for things you probably never thought about).
The keyword "register" has been deprecated since the 2011 C++ standard; see "Remove Deprecated Use of the register Keyword". It should therefore not be used.
In my own experiments I found that debug code generated by gcc (v8.1.1) does differ if the "register" keyword is used; the generated assembly code allocates designated variables to registers. Benchmarks even showed that this code ran faster (than code without "register"). This is irrelevant, however, as release (optimised) code showed no differences (ie, using "register" had no effect). Vacbob states here that if any optimization is enabled, then gcc ignores "register". My own tests confirm this.
So, in summary, don't use "register" and if debug code appears to run faster when "register" is used, bear in mind that the optimized release code will not.

Hints for the compiler to help it with the optimization task

The const and volatile chapter on the 'Surviving the Release Version' Article gave me the idea that the compiler can use the const keyword as hint for its optimization job.
Do you know some other optimization-hints for the compiler or design principles for functions so that the compiler can make them inline?
By the way, do you declare primitive-type function parameters as const or const reference (like void foo(const int i) or void foo(const int& i))?
Thanks!
It is rare that const qualification can help the compiler to optimize your code. You can read more about why this is the case in Herb Sutter's "Constant Optimization?"
Concerning your last question: in general, you should prefer to pass by value things that are cheap to copy (like fundamental type objects--ints and floats and such--and small class type objects) and pass other types by const reference. This is a very general rule and there are lots of caveats and exceptions.
As soon as you enable some optimization the compiler will notice that the parameter i is never modified, so whether you declare it as int or as const int doesn't matter for the generated code.
The point of passing parameters by const & is to avoid needless copying. In case of small parameters (one machine word or less) this doesn't lead to better performance, so you shouldn't do that. foo(int) is more efficient than foo(const int&).
There's no practical benefit to either form. If the type is less than a single machine word, take it by value. The other thing is that a modern compiler's semantic analysis is way above what const can and can't do, you could only apply optimizations if it was pre-compiled or your code was VERY complex. The article you linked to is several years old and the compiler has done nothing but improve massively since then.
I don't think the compiler can use const keyword for optimization since at any point the constness can be casted away.
It is more for correctness than optimization.
A few "general compiler" things off the top of my head.
const as a hint that a variable will never change
volatile as a hint that a variable can change at any point
restrict keyword
memory barriers (to hint to the compiler a specific ordering) - probably not so much an "optimisation" mind you.
inline keyword (use very carefully)
All that however should only come from an extensive profiling routine so you know what actually needs to be optimised. Compilers in general are pretty good at optimising without much in the way of hints from the programmer.
If you look into the sources of Linux kernel or some such similar projects, you will find all the optimisation clues that are passed on to gcc (or whichever compiler is used). Linux kernel uses every feature that gcc offers even if it is not in the standard.
This page sums up gcc's extensions to the C language. I referred C here because const and volatile are used in C as well. More than C or C++, compiler optimization appears the focus of the question here.
I don't think the real purpose of const has much to do with optimization, though it helps.
Isn't the real value in compile-time checking, to prevent you from modifying things you shouldn't modify, i.e. preventing bugs?
For small arguments that you are not going to modify, use call-by-value.
For large arguments that you are not going to modify, use either call-by-reference or passing the address (which are basically the same thing), along with const.
For large or small arguments that you are going to modify, drop the const.
BTW: In case it's news, for real performance, you need to know how to find the problems you actually have, by profiling. No compiler can do that for you.