After reading this post: Is there a downside to declaring variables with auto in C++?
I was asking myself: Is really no one of the answerers aware of auto not beeing a type but a storage-class specifier.
Or is auto since C++11 something different as the storage-class specifier in plain C?
If so, does this break the compability between C and C++?
(I'm aware that they official never were supporting each other in anyway, but my experience was that the C++ comittee tryed to stay as close to C as possible when evver it was acceptable. But now changing an obsolete, but abyway existing keyword instead of just adding a new one. Why here doing such a break of consistens?)
As of c++11 auto means to infer the type. It was used because adding a new keyword would have caused more c++ programs to break. As a storage specifier, auto is useless because it is the default if no specifier is added.
The only alternative was to follow the approach used in C generics of using a name starting with an underscore. This would have lead to an ugly keyword, that is meant to be regularly used.
Related
This question already has answers here:
Why do the older C language specs require function-local variables to be declared up-front?
(3 answers)
Closed 7 years ago.
I have been going through a bit of history of C, and I find that in earlier versions of C, like in C89 standard, it is mandatory to declare variables at the beginning of a block.
But I also find there are some relaxations from C99 standard specification, where variable can be declared anywhere before it is used.
My question is why the earlier versions made it mandatory? my emphasis is to know if there was any technical difficulties in designing the compiler at those days, that prevented them identifying declarations at any point.
Also, with a compiler design perspective I understand, with such a restriction in C89, it is easy to handle variable declarations and usage with the help of an intermediate file to store the mappings. But are there methods that can handle the case without using an intermediary file, say some memory based storage?.
If the compiler sees a consolidated list of all the local/automatic variables up front, it can immediately work out the total amount by which to move the stack pointer to reserve stack memory for them - just one operation on the stack pointer. If it handles the variables in dribs and drabs as they're encountered in the function, moving the stack pointer incrementally, then there ends up being more opcodes dedicated to stack setup and stack pointer updates. It's important that the stack pointer be up to date whenever a further function call's performed. Newer compilers do a tiny bit of extra work to patch back in the amount by which to move the stack pointer after all the function's been considered. (I'd hazard that the effort's so minimal that the early Standard was shaped more by the conceptual appeal of knowing what to do up front than the effort of being more flexible, but if you just want to get something working - why make extra efforts?)
C99 Rationale didn't directly explain why it was not permited in C89, but did say it was added in C99 because it was permited in other languages and the it has been found useful.
Rationale for International Standard — Programming Languages — C
§6.2.4 Storage durations of objects
A new feature of C99: C89 requires all declarations in a block to occur before any statements. On the other hand, many languages similar to C (such as Algol 68 and C++) permit declarations and statements to be mixed in an arbitrary manner. This feature has been found to be useful and has been added to C99.
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.
Theoretical question only - why i can't write such code:
auto auto foo = 0;
First auto keyword - storage class specifier (yeah, i know that it's useless and deprecated in C++11), second auto keyword - auto type-specifier.
So what's wrong?
And again - i don't really want to use this in real code.
The auto storage class specifier is not "useless and deprecated in C++11," it has been removed entirely. The auto keyword is no longer a storage class specifier and cannot be used as one.
In C++11, auto is a simple type specifier.
From the Stroustrup's FAQ:
....The old meaning of auto ("this is a local variable") is now
illegal. Several committee members trawled through millions of lines
of code finding only a handful of uses -- and most of those were in
test suites or appeared to be bugs.
Which indicates there's much not code used using "auto" as storage specifier.
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.
Microsoft Visual C++ compiler has the property declaration construction
__declspec( property( get=get_func_name, put=put_func_name ) )
Is there a compiler independent version of Microsoft C++ __declspec(property(...)) or another analogs?
No.
As usual, an identifier preceded by __ is reserved to the compiler. In C++03 you have __cpluscplus (to identify C++ vs C), __FILE__ and __LINE__. All those are preprocessor entities.
In C++0x, the difference is blurred by the introduction of the __attribute__ word which is the first I know of that has semantics value, but it still does not do what you're looking for.
EDIT: Addressing #James spot on comment.
As Nicola Musatti says, there was a Borland proposal, primarily because Borland Delphi uses Properties heavily, and C++Builder (their C++ 'equivalent' to Delphi) therefore requires it.
In C++Builder, the code looks a bit like this.
__property __int64 Size = {read=GetSize, write=SetSize};
No. Similar mechanisms were proposed to the C++ standard committee but none was ever accepted (Here is one such proposal from Borland).
I've seen template based toy implementations, but they tend to be too inconvenient to be of practical use, the major problems being:
As nested class instances are not members of the enclosing class (as are Java inner class instances), you have to explicitly "connect" a property to its enclosing class, which makes declaration and initialization cumbersome.
There is no way to call function-like entities without parentheses, so you cannot invoke a custom-made property as if you were accessing a variable.