The most recent c++ feature(that is also quite modern) that I found about is attributes. They seem quite useful for signalling the compiler, but apart from that, what other more specific uses can attributes have? How can custom attributes be created and used and what is the main idea behind the use of c++ Attributes? If the topic is too broad, im particularly interested in attributes with functions.
By attributes I mean these: https://en.cppreference.com/w/cpp/language/attributes
Attributes (that is, attributes as a feature of the C++ language, not compiler-specific __declspec or __attribute__ attributes) are kind of a C++ hack. They're a solution to meta-problems with the evolution of the C++ language.
For example, keywords. There's a lot of C++ code out there, and any new version of the language that adds new keywords needs to avoid breaking any code that might use that keyword for an identifier. So any language feature that might want to spell something out explicitly has a really high bar for passing standardization. That is, it'd had better be worth it.
But attributes are cheap; they don't conflict with any existing code. Consider wanting to declare that a function does not return normally (ie: always throws an exception or calls std::terminate or whatever). That feature it doesn't really govern the behavior of the program; it's more an indicator to the compiler/user about how that function is going to behave. So it's not a feature worth breaking the code of someone who just so happened to name a variable noreturn.
But you can have the [[noreturn]] attribute, since that won't break anybody's code.
Another meta-problem attributes solve is "fixing" things that maybe weren't good ideas in the first place. For example, case labels in switch statements automatically fall-through to the next one if you don't explicitly break. While fall-through behavior is useful, it's the wrong behavior to have as a default, since 90+% of the time, you intend to break.
But you can't go and change how case labels work and introduce a fallthrough keyword. That would break everybody's code that already uses the implicit fall-through behavior.
But you can add a [[fallthrough]] attribute. It doesn't mean anything within the language, but if a compiler sees it, then it can know that you meant to fall-through to the next label. Furthermore, you can now turn on compiler warnings about fall-through behavior, so that any fall-through that happens without the [[fallthrough]] attribute will give you a warning. And you can even choose to make that warning an error, thus effectively "fixing" the language. For you.
Most C++ attributes are like that: tags for code that are too trivial/non-functional to bother burning a keyword for, or indicating something useful about the code to the compiler that isn't really part of the langauge.
Related
I was told that #defining language keywords is undefined behaviour. How does this play with the following facts:
Users can #define names that are not keywords in their code.
The language can get new keywords that used not to be keywords over time.
Users should be able to compile old code with new compilers and get a compile-time diagnostic rather than undefined behaviour if any construct they used has ceased to be supported.
#3 is obviously my assumption but I consider this assumption essential as newer compilers tend to be better and "knowing the whole extent of the current law" is a theoretical legal assumption that does not apply to software developers, I hope (if the compiler assumed otherwise, it could replace any compile-time error in the code with whatever undefined behaviour it pleases).
#3 is not the case and has never been guaranteed by anyone. While the C++ committee does not like to create backwards incompatibilities that don't noisily break, they still sometimes do it.
You shouldn't expect a thing that you were not told to expect.
And yes, it's possible that adding a new keyword breaks silently for those who #defined that keyword. This is one of the many reasons why users are told to use ALL_CAPS for their #define names, since keywords will almost certainly not be in ALL_CAPS.
C++ standards are not fully backwards-compatible. That doesn't hold you back from using a modern compiler.
If you want to compile old code with a new compiler, you set the C++ version explicitely with a flag. For example, with GCC, the default C++ version varies with version. To set it explicitely, you use the -std option, e.g. std=c++11 or std=c++0x.
Then any keywords introduced after this version will not be in effect so you will not run into undefined behavior. If you would like to use the newer language features on the other hand, you need to go through the documented newly introduced keywords and some subtleties that changed and review your code accordingly.
#3 Users should be able to compile old code with new compilers and get a compile-time diagnostic rather than undefined behaviour if any construct they used has ceased to be supported.
This is a good thing to strive for, but there is technically no such guarantee.
#2 The language can get new keywords that used not to be keywords over time.
Yes. Because of desire to keep existing programs working, the standards committee is usually against introducing new keywords, but it does happen regardless.
For those cases where a new keyword is introduced, there is a trick to avoid name collisions (with high probability) with your macros: Use upper case. None of the C++ keywords with the exception of _Pragma use upper case, and this is likely to stay true in future. For other identifiers than macros, using keywords makes the program ill-formed, so you are guaranteed a diagnostic.
To find out all the (possible) problems that existed in the program, we had better turn on all the debug tools of the compiler. The tool will always tell us something like "remark #7712: This variable has not been used.".
In many cases, in order to keep some rules, I have to keep some input and output without using them. At the same time, I want to keep the debug tool turned on.
Can we do something by standard grammar to tell the compiler we really mean to do it and do not report any warning about it?
The Fortran standard sets out the rules for correct programs and requires that compilers identify any breach of those rules. Such breaches, which cause compilation to fail, are generally known as errors.
However, programmers make many mistakes which are not errors and which a (Fortran) compiler is not required to spot. Some compilers provide additional diagnostic capabilities, such as identifying unused variables, which go beyond what the standard requires. The compilers raise what are generally known as warnings in these cases. This type of mistake does not cause compilation to fail. Compilers also generally provide some means to determine which warnings are raised during compilation, so that you can switch off and on this diagnostic capability. For details of these capabilities refer to your compiler's documentation.
The standard is entirely silent on this type of mistake so, if I understand the question correctly, there is nothing
by standard grammar to tell the compiler we really mean to do it and
do not report any warning about it
The simplest thing (besides of course not declaring things you don't use)
may be to simply use the variables.
real x
x=huge(x) !reminder x is declared but not used.
at least makes gfortran happy that you have "used" the variable.
In C++ it is possible to use the static keyword within a translation unit to affect the visibility of a symbol (either variable or function declaration).
In n3092, this was deprecated:
Annex D.2 [depr.static]
The use of the static keyword is deprecated when declaring objects in namespace scope (see 3.3.6).
In n3225, this has been removed.
The only article I could find is somewhat informal.
It does underline though, that for compatibility with C (and the ability to compile C-programs as C++) the deprecation is annoying. However, compiling a C program directly as C++ can be a frustrating experience already, so I am unsure if it warrants consideration.
Does anyone know why it was changed ?
In C++ Standard Core Language Defect Reports and Accepted Issues, Revision 94 under 1012. Undeprecating static they note:
Although 7.3.1.1 [namespace.unnamed] states that the use of the static keyword for declaring variables in namespace scope is deprecated because the unnamed namespace provides a superior alternative, it is unlikely that the feature will be removed at any point in the foreseeable future.
Basically this is saying that the deprecation of static doesn't really make sense. It won't ever be removed from C++. It's still useful because you don't need the boilerplate code you would need with unnamed namespace's if you just want to declare a function or object with internal linkage.
I will try to answer your question, although it is an old question, and it does not look very important (it really is not very important in itself), and it has received quite good answers already. The reason I want to answer it is that it relates to fundamental issues of standard evolution and language design when the language is based on an existing language: when should language features be deprecated, removed, or changed in incompatible ways?
In C++ it is possible to use the static keyword within a translation unit to affect the visibility of a symbol (either variable or function declaration).
The linkage actually.
In n3092, this was deprecated:
Deprecation indicates:
The intent to remove some feature in the future; this does not mean that deprecated features will be removed in the next standard revision, or that they must be removed "soon", or at all. And non-deprecated features may be removed in the next standard revision.
A formal attempt to discourage its use.
The latter point is important. Although there is never a formal promise that your program won't be broken, sometimes silently, by the next standard, the committee should try to avoid breaking "reasonable" code. Deprecation should tell programmers that it is unreasonable to depend on some feature.
It does underline though, that for compatibility with C (and the ability to compile C-programs as C++) the deprecation is annoying. However, compiling a C program directly as C++ can be a frustrating experience already, so I am unsure if it warrants consideration.
It is very important to preserve a C/C++ common subset, especially for header files. Of course, static global declarations are declarations of symbol with internal linkage and this not very useful in a header file.
But the issue is never just compatibility with C, it's compatibility with existing C++: there are tons of existing valid C++ programs that use static global declarations. This code is not just formally legal, it is sound, as it uses a well-defined language feature the way it is intended to be used.
Just because there is now a "better way" (according to some) to do something does not make the programs written the old way "bad" or "unreasonable". The ability of using the static keyword on declarations of objects and functions at global scope is well understood in both C and C++ communities, and most often used correctly.
In a similar vein, I am not going to change C-style casts to double to static_cast<double> just because "C-style casts are bad", as static_cast<double> adds zero information and zero safety.
The idea that whenever a new way to do something is invented, all programmers would rush to rewrite their existing well-defined working code is just crazy. If you want to remove all the inherited C ugliness and problems, you don't change C++, you invent a new programming language. Half-removing one use of static hardly makes C++ less C-ugly.
Code changes need a justification, and "old is bad" is never a justification for code changes.
Breaking language changes need a very strong justification. Making the language very slightly simpler is never a justification for a breaking change.
The reasons given why static is bad are just remarkably weak, and it isn't even clear why not both objects and function declarations are deprecated together - giving them different treatment hardly makes C++ simpler or more orthogonal.
So, really, it is a sad story. Not because of the practical consequences it had: it had exactly zero practical consequences. But because it shows a clear lack of common sense from the ISO committee.
Deprecated or not, removing this language feature would break existing codes and annoy people.
The whole static deprecation thing was just wishful thinking along the lines of "anonymous namespaces are better than static" and "references are better pointers". Lol.
I always assumed that fortran passed entities "by reference" to a dummy argument. Then I got this answer (the actual argument of the answer was related, but not on this)
The standard never specifies that and,
indeed goes quite a lot out of its way
to avoid such specification. Although
yours is a common misconception, it
was not strictly accurate even in most
older compilers, particularly with
optimization turned on. A strict
pass-by-reference would kill many
common optimizations.
With recent standards,
pass-by-reference is all but
disallowed in some cases. The standard
doesn't use those words in its
normative text, but there are things
that would be impractical to implement
with pass-by-reference.
When you start getting into things
like pointers, the error of assuming
that everything is pass-by-reference
will start making itself more evident
than before. You'll have to drop that
misconception or many things wil
confuse you.
I think other people have answered the
rest of the post adequately. Some also
addressed the above point, but I
wanted to emphasize it.
See here for attribution.
According to this answer, then, there's nothing in the standard specifying how data are shipped from the caller to the callee. In practical terms, how this should be interpreted in terms of actually working with it (regardless of the practical effects resulting from how compilers implement the standard) in particular when it comes to intent() specification?
Edit: I'd like to clarify my question. What I am trying to understand is how the standard expects you to work when you are performing calls. Given that the actual compiler strategy used to pass entities is undefined by the standard, you cannot in principle (according to the standard) expect that passing an argument to a function will actually behave as a "pass-by-reference", with all its related side-effects, because this behavior is compiler and optimization dependent. I assume therefore the standard imposes you a programming style you have to follow to work regardless of the actual implementation strategy.
Yes, that's true. Fortran standard doesn't specify the exact evaluation strategy for different INTENT attributes. For example, for a dummy argument with INTENT(OUT) some Fortran compiler can use call-by-reference or call-by-copy-restore evaluation.
But I do not understand why do you really need to know which evaluation strategy is used? What is the reason? I think Fortran do it right. Humans concern is (high-level) argument intent, and computers concern is (low-level) evaluation strategy. "Render unto man the things which are man’s and unto the computer the things which are the computer’s." N. Wiener
I think the standard contains enough information on the usage of different INTENT attributes. Section "5.1.2.7 INTENT attribute" of Final Committee Draft of Fortran 2003 standard (PDF, 5 MB) is a good starting point.
As the others have said, you don't have to know how the compiler works, as long as it works correctly. Fortran >=90 allows you to specify the purpose of an argument: input, output or both, and then the compiler takes care of passing the argument. As long as the compiler is correctly implemented so that both sides (caller and callee) use the same mechanism, why should the programmer care? So the Fortran standard tries not to limit how compiler writers implement their compilers, allowing them to design and optimize as they wish.
In terms of programming style, decide the purpose of your procedure arguments, and declare them with the appropriate intent. Then, for example, if you accidentally try to modify an intent(in) argument in a procedure, the compiler will issue an error message, preventing you from making this mistake. It might even do this before emitting object code, so the actual argument passing mechanism has nothing to do with enforcing this requirement of the language.
C is a lower-level language and the programmer needs to choose between passing by value or by reference for various reasons. But for problems such as scientific programming this is an unnecessary aspect to have to control. It can be essential in embedded or device driver programming.
If there is a reason that you must control of the argument passing mechanism, such as interfacing to another language, Fortran 2003 provides the ISO C Binding (which is already widely implemented). With this you can match the C method of argument passing.
I'm not sure I understand your question, but one way of seeing things is that as long as one writes standard-conforming code, one does not need to be concerned with how argument passing is implemented. The compiler makes sure (well, barring compiler bugs, of course) that arguments are passed in a way that conforms to the standard.
Now, if you play tricks e.g. with C interop or such, say by comparing argument addresses you might be able to determine whether the compiler uses pass by reference, copy-in/copy-out or something else in some particular case. But generally speaking, at that point you're outside the scope of the standard and all bets are off.
Lately as part of my day job I've been learning IBM Rhapsody and using it to generate code in C++ from the UML.
Yesterday it struck me that it might be cool to think about adding state machine support to my C++ compiler, so I jotted a few notes here: http://ellcc.org/wiki/index.php/State_machines_and_Active_Classes
My motivations for doing this are:
It seems like a cool idea.
The compiler could do much better semantic checking (with better error checking) than the current Rhapsody/normal C++ compiler.
There are many optimization possibilities available when the compiler itself understands the state machine structure.
I may try to extend my grammar to except something like the proposal to see how well it works.
What is your opinion of the proposal? Does it seem readable? Does it seem worthwhile?
Edit:
Thanks for the answers recommending specific libraries to do state machines, but that wasn't my question. I've implemented many state machines using both libraries and code that I've written.
I was really looking for ideas, criticism, etc. about the design of a state machine extension to a C++-like language, not whether this change would be appropriate for addition to standard C++. Think of it as a domain specific extension, where my my domain is real-time control applications.
I've started implementation of the extension in my compiler as described here: http://ellcc.org/wiki/index.php/State%5Fmachines%5Fand%5FActive%5FClasses
So far the concept hasn't had to change much going from proposal to implementation but there have been a few changes in details and I'm refining my understanding of the semantics of the problem.
Time will tell whether the whole concept has any value, however. ;-)
With a few exceptions, C++ has traditionally been extended using class libraries, not new keywords. State machines can easily be implemented using such libraries, so I don't think your proposal has much of a chance.
One problem I see in your proposal is the use of 'goto' to go to another state. What happens if I want to use goto in my own code within a state transition?
Excellent work developing what you've done. Something like you've done probably is possible, but I'm doubtful it would ever get into the C++. Most changes that make it into the language itself are included only to allow people to write more useful and powerful libraries.
There's a library here that provides support for state machines. I haven't tried it, but it might interest you, and you may be able to combine your ideas with a library like this to allow other people to make use of it.
http://www.boost.org/doc/libs/1_34_1/libs/statechart/doc/index.html
Or, you could develop your own extension as you suggest, and it would at least be useful for you. Microsoft implement some extension keywords, so there is no reason why you couldn't create your own extended version of C++.
Keep the new ideas coming.
You should take a look at how another smart developer added State machine support to a C-like language: UnrealScript Language Reference. See the section named "States".
UnrealScript supports states at the
language level. In UnrealScript, each
actor in the world is always in one
and only one state. Its state reflects
the action it wants to perform. For
example, moving brushes have several
states like "StandOpenTimed" and
"BumpOpenTimed". Pawns have several
states such as "Dying", "Attacking",
and "Wandering". In UnrealScript, you
can write functions and code which
exist in a particular state. These
functions are only called when the
actor is in that state
It's an interesting idea, but I think you'd actually have better luck creating your own domain-specific language for state machines than officially extending C++. C++ is designed as a very general-purpose programming language. I think Boost has proven that C++ is flexible enough that most features can be implemented nicely using libraries. It also evolves very slowly, to the extent that standard C++ still doesn't even have built-in threading support as of 2009, (it is planned in 0x). So it's unlikely the committee would consider this addition for some time.
Your solution does not look like it has any advantages to a template- or preprocessor-macro-based solution.
I am also not sure, how you can provide better semantic checking. And I doubt that you can apply many useful code optimizations.
However, to allow better optimizations and semantic checking, you should also replace "goto" with a new keyword (e.g. __change__ newState), and disallow goto for state changes! Allow goto for local jumps as usual.
Then the compiler can extract a list of possible transitions.
Read your proposal, have the following comments:
There's actually no keyword to declare and define an actual state machine! Do you assume a single global state machine (and thus a single global state)? How does that relate to __active__ ?
The closest comparable construct in C++ is actually the enum. Why not extend it?
There seems to be some connection between defined events and states, but I fail to see how it's implemented.
Why are threads and timers needed at all? Some use cases of state machines may benefit from them, but a good proposal should keep these seperate. Most importantly this should allow the use of standard C++0x threads.
Personally, I would extend the enum syntax:
enum Foo {
red, blue, green; /* Standard C++ so far - defines states. State list ends with a ; not a , */
Foo() { *this = red; } // Reuse ctor syntax, instead of __initial__
~Foo() { } // reuse dtor syntax, instead of __onexit__
void Bar() {/**/} // Defines an event, no return value. Doesn't need keyword __event__
};
It follows naturally that you can now declare your events in a header, and define them in a .cpp file. I don't even need to suggest the syntax here, any C++ programmer can guess that at this point. Add a bit of inheritance syntax for combined states:
enum DrawingObject : public Shape, public Color { /** } // allows (red && circle)
and you're pretty much at the point where your proposal is, without any new keywords, all by reusing an already familiar syntax.