GCC 6.1 Released
gcc.gnu.org
gcc.gnu.org
http://paste.debian.net/plain/442020
(I excluded the po files, as that gives one user too much credit, since he just checked in the translations, but didn't write them himself.)
This is a rather unusual contribution graph. Most I've seen follow a very stark power law, with one contributor doing over 90% of the work, and the second contributor doing around 5%. This graph shows a lot more collaboration from many people. The development of gcc seems healthier than ever!
Is it a sign of health (diverse community) or a sign of illness (no active technical lead, outsiders driving development in fragmented directions)? I don't think you can tell just by looking at the graph.
edit: Upon closer inspection, it appears that Arnaud Charlet is currently the top one because he's committed a lot of Ada code for other people from AdaCore. It would take some teasing out of the GNU changelogs instead of the svn log to figure out who really wrote what. So, looks like Jakub really is the leader.
[0] Example commit: https://github.com/gcc-mirror/gcc/commit/b0c0971248103432dd6...
It would be interesting if most of his contributions recently have shifted to gccgo, though!
Can anyone chime in about how a developer would choose gcc over clang (and vice versa). I have to admit that even though I write in c++, I seldom pay attention to which compiler I would use for x vs y feature, etc. Compilers feel like a black-box to me. I don't go inside it.
Edit: I don't know about Windows, I know gcc is available. I haven't looked if clang is.
Edit 2: Intel also makes compilers, to which I own, but never use. I guess I feel like I am not doing anything specific to Intel
Also, different dev environments offer different tools. A nice benefit of running in lots of environments was that I often could pick between the best tools of any platform whenever I had a problem they could help solve.
Clang is much faster at compiling though. It's a trade off.
risc / cisc gathered around each other, clang / gcc...
progress by antagonism
http://stackoverflow.com/questions/18976922/how-to-use-the-g...
They are not supported. In C++11 you can use lambdas:
auto const local_func = [&](...) {
...
};
And then later: local_func(...);It is/was. It could be used to manually create a lambda function.
This restriction has been lifted in C++11.
[1] Namely, -Wdouble-promotion, big-endian ARM interrupt handlers, -fstack-usage, -Og, -fno-delete-null-pointer-checks, -falign-functions
But actually, what I'd rather like is -fno-optimise-based-on-undefined-behaviour.
In my particular case, I'm programming in a microcontroller environment where there is ordinary RAM at the NULL address. Dereferencing NULL therefore doesn't halt the program at all.
X *foo = ...;
if (foo) foo->bar();
But this code will be: X *foo = ...;
foo->bar();
if (foo) { ... }
Since foo is dereferenced unconditionally, the compiler is allowed to assume that it will not be null in the above code, and therefore the test on the third line to determine whether foo is null or not is useless and can be omitted.That won't nearly get everything, but loop optimization in C relies on undefined behavior a lot of the time, so you'll get to see how much you need it.
For a summary from the OpenBSD perspective, see here: http://marc.info/?l=openbsd-misc&m=137530560232232&w=2
clang is available for Windows as clang-cl from here: http://llvm.org/releases/download.html
Here's the status page for compatibility with MSVC (clang 3.9, i.e. current development version): http://clang.llvm.org/docs/MSVCCompatibility.html
2. GCC is generally considered to produce better binaries.
3. Smart projects will support both and test with both. Before, even though projects tried to be portable, GCC was the only compiler most developers had available. Now they have two (although clang does try to support almost everything GCC does, so it doesn't say a huge amount about portability).
4. If you want to quickly see whether an optimization was applied (like inlining or loop unrolling), looking at LLVM is more approachable, so clang is nice for that.
I see this more and more often on Reddit, from posters I assume are millennials, and I am interested in the psychology of this error. Why do you put a "to" before "which"? You would not say "I own to an Intel compiler".
I never see people make this mistake with other pronouns, either: for instance, they will correct turn "I saw pg yesterday" into "pg, whom I saw yesterday". What is it about "which" specifically that makes it hard for kids to use?
Every time I hear about new GCC releases all I can think of is how the compiler wars have clearly inspired lots of new feature development. From the high level it seems like GCC is still catching up with clang. Are there cases where GCC has leapt ahead of clang in some features?
Unless you target a feature or cpu architecture that only one of them supports, it is close to a coin toss nowadays which compiler builds the faster binary.
Honest question, in production, is this sort of a thing pretty much a non-issue?
Edit: Sorry, to be clearer, I meant to ask, effect of stuff like changing defaults between different versions. Perhaps, it is a non-issue because most production code is (/maybe) version locked.
Also, a little vague, but out of curiosity, how often do C / C++ shops upgrade to the latest and greatest?
There aren't any (AFAIK) explicit breaks of '98 code in '14. So the theory is that code should compile with the new compiler fine, but you'll likely hit some issues.
Check out Scott Meyers book: Effective Modern C++ for the deltas.
Then there's a keyword that was re-purposed to do something totally different: in C++, auto used to be a storage duration specifier. In C++11 it is used to indicate type inference.
There were also changes that, while not breaking source compatibility, basically required implementations to break binary compatibility going from C++98 to C++11. This in particular resulted in a gigantic mess.
With regard to breaking changes the C++ committee is not anywhere near as conservative as the one for C.
I might be misunderstanding something, but gcc 6.1 does make C++14 the default.
Very very slow, specially in the enterprise and embedded areas.
Back when I used to work in C++, the compilers at my employers were version locked by IT admins, not developers. To make sure all company development projects were in sync.
Getting a new compiler version was akin to have a new OS version deployed across the company, from overall process.
> C++ Concepts are now supported when compiling with -fconcepts.
See "Version Numbering Scheme for GCC 5 and Up" here https://gcc.gnu.org/develop.html .
They're also using the version 0 in the second component to indicate prereleases. GCC 6.0.0 was the development version of GCC 6. The release candidate was 6.0.1. The first release of GCC 6, which came out today, is 6.1.0. Then there will be development under the name 6.1.1, and the first bugfix release on the GCC 6 line will be 6.2.0. The amount of change between 6.1.0 and 6.2.0 is equivalent to the amount of change between 4.9.0 and 4.9.1 in the old numbering scheme.
(1) if (this == NULL): this is super useful in non-virtual functions, because NULL is the object that subclasses all classes, so the only universal error object.
(2) memset in operator new: in C++03, we did not have initialisers inside struct{}, so quicky zero the obj to avoid error-prone manual inits of all embedded ints.
This is really becoming ridiculous. Having a notion of how C/C++ corresponds to what the machine will do seems to be more and more regarded as evil.
You might get a pointer to NULL+8 or something like that if the class inherents from more than one class.
Maybe you should just write compliant code after all.
Not counting true compiler bugs of course.
Edit: The release notes at https://gcc.gnu.org/gcc-6/changes.html mention three programs that apparently will break:
Value range propagation now assumes that the this pointer of C++ member functions is non-null. This eliminates common null pointer checks but also breaks some non-conforming code-bases (such as Qt-5, Chromium, KDevelop)
Of course I do. I call it "customers".
The C standard is very generous in terms of undefined behavior freedom.
If you're using some other definition, then say so, otherwise your comments make no sense.
They are free to do that and still be compliant, after all UB means anything goes.
It is the GNU compiler collection, after all. I'm actually particularly excited about a new release of gdc myself. I've been reading Alexandrescu's excellent The D Programming Language, and I think it may be just the better C++ that I always wanted, ahead of Golang and Rust.
Who was complaining about that?
> when they put in god knows how many hundreds of hours of work improving, we complain when we might have to spend a few to go back through our programs and make sure everything's okay. We want everyone else to do the work for us.
Their whole job is to compile our programs - what else is a compiler good for? I don't know who GCC's users are these days - people who care more about benchmarks than working code? Because that seems to be who they're optimising for. Then again I suppose that's the entirety of C/C++'s market these days.
That said, I agree with treehau5.
So compilers need to judge what is "perfectly obvious to any reader", now? And you're willing to deal with the fallout of different compilers having different conceptions of "perfectly obvious"?
That's... an ambitious project.
Maybe your time would be better spent convincing the C++ committee to define some more behavior instead of leaving it undefined.
If all you want the compiler to do is make a working program, just disable all optimisations.
Whether it's possible to salvage C/C++ by specifying some safe subset (for some ideas towards this see e.g. Regehr's "safe C" or DJB's "boring C") without sacrificing too much performance remains to be seen. Another option, then, would be to start over from a clean slate, e.g. Rust.
While most likely having less of an impact on the world at large, at least personally I find learning myself Rust more fulfilling than the prospect of fighting political battles in the ISOC committée. YMMV, of course.
tl;dr: The above has all to do with the specification of the C and C++ languages rather than compiler writers attempt to exploit the spec to its fullest potential. So yeah, as long as "compiler goodness" is (marketing-wise at least) determined by SPECcpu scores, it's unfair to blame compiler writers for this mess.
> SQLite’s vdbe struct has a member called aMem that uses 1-based array indexing. To avoid wasting an element, this array is initialized like this: p->aMem = allocSpace(...); p->aMem--;
> the culture of developers tends to the view that something which has
> always worked in every important implementation should be allowed and
> continue to work in new implementations
Yes, and X3J11 stated as its first guiding principle, > Existing code is important, existing implementations are not.
But then they committed the original sin against “simple C” by inventing ‘volatile’, breaking systems code written when p[0]=x was expected to write to location p. Unlike ‘const’, with which the programmer grants additional license to the compiler, C89 granted the non-‘volatile’ license to the compiler by default. In retrospect, I think C would have been better off retaining do-what-I-wrote as the default, and requiring the programmer to grant the compiler license to do otherwise. C already had the ‘register’ keyword to indicate that a variable should be compiled for speed and need not be literally preserved according to a naïve reading of the code.But if I tried hard enough, I'm sure I could find a few that have been run through some sort of formal verification tool.
Whether I could or not doesn't change my assertion at all though.
=> You need stronger arguments to make the "absolutely not true" claim.
By all practical definitions, and by any measurable way to declare a codebase free of undefined behavior, ours is.
And I bet others out there are too. There are formal verifiers for C programs that are used in industries. Unless there's a bug in the verifier, the program that it verifies is, by definition, free of undefined behavior.
Just because you, or the open source projects you use, don't code to the standards, or don't have or use the tools that help you do so, doesn't mean there aren't industries out there who can, and do.
Here's a list of undefined behaviors that's almost impossible to get rid of:
* Data race. This is particularly fun for anyone who started doing multithreaded code pre-C11/C++11, since volatile does not let you use code across multiple threads without locking.
* Signed integer overflow. Are you sure that there is absolutely no input to your program that would not cause one of your thousands of signed arithmetic operations to overflow?
* Buffer overflow. This is something like 90% of all security vulnerabilities.
* Uninitialized variables. Note that -Wuninitialized doesn't catch all cases, although this is relatively easy to mitigate with a paranoid style guide.
* Strict aliasing rules. Better yet, if you have any sort of custom memory allocation scheme, you're pretty much guaranteed to break this, since the only way you can access an object with a dynamic type of bytes (signed/unsigned char) is via signed/unsigned char. Functions like memcpy or malloc cannot legally be written in C without breaking this behavior. Also, there is not (to my knowledge) any dynamic checker for violations of this property, unlike the other things in this list.
Your program probably has undefined behavior. You just don't know it yet, and your compiler hasn't figured out how to squeak out a 0.5% speedup from screwing you over because of it yet.
Sorry, I don't understand this. Does this mean that these C standard library functions cannot be written in C without breaking the ISO C standard?
The rest are clearly taught in CS100 to be doorways to chaos. In particular, complaining that volatile doesn't get rid of the need for locks is just making noise. Might as well complain that auto doesn't get rid of the need for locks. They are both unrelated to threading.
Overflow checking is sometimes done like this (where a is a signed integer):
if (a + 100 < a) ...
Of course this invokes undefined behavior, and some people get angry when compilers remove the check: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475- Data race leads to subtle bugs on all languages and runtimes, including Java and C#. They are just not called undefined behavior in those languages.
- char* and unsigned char* are allowed to alias any pointer. This is one of the exceptions to the strict aliasing rule.
That's because they aren't. You might get incorrect results or exceptions or whatnot, but NOT Undefined Behavior aka. nose-demons. What can happen in cases of data races is always constrained by the VM model. (Obviously, this is modulo bugs in the actual VM implementation, but that probably goes without saying.)
The same applies to Java/C# when data race is present. The JIT must be generating optimized codes assuming that no data race occurs, because it is impossible to detect or correct them (at least in current implementation). When you do have data race, the bugs will be as subtle and Schrödinger's as if data race occurs in a C program.
For the details see e.g. http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html...
First, citation needed.
Second, the programs I work on would fall outside of your "virtually every".
> [big list of things]
This list doesn't prove anything. There's a similar list in the standards themselves. That's how we know what to avoid.
Oh, and we have an in-house static analysis program that catches all of those. And more.
Our code simply has no undefined behavior. It passes our static analysis program, it passes UBSAN, and no compiler has ever miscompiled our code (unless it was due to a compiler bug).
You can try all you like, but there's no way for you to convince me that our code has undefined behavior. And there are plenty of projects out there similar to ours.
> if you have any sort of custom memory allocation scheme, you're pretty much guaranteed to break this
Not true. You should learn about the aliasing rules before you speak authoritatively about them.
> Functions like memcpy or malloc cannot legally be written in C without breaking this behavior
Also not true.
> Your program probably has undefined behavior.
The chances of that are much less than the chances of you not knowing what you are talking about.
In that case (sqlite) code that passed UBSan, ASan, valgrind, and compiled correctly on all current compilers was studied. A new dynamic undefined behavior checker found additional UB defects at a rate over 1 per thousand lines of code.
I would believe your codebase could have a defect rate one, maybe even two orders of magnitude lower. But short of a formal code-correctness proof, better than that seems unlikely.
I do know the strict aliasing rules quite well. As I said in a cousin post, the set of permissible accesses to a lvalue are governed by the dynamic type of an object. As a consequence, strict aliasing queries are not symmetric, which is to say, P* could point to an object of type Q* but not vice versa. The case where this will come up is with signed/unsigned char. If you have a char foo[]; as the dynamic object, it is positively illegal to access that with anything other than unsigned or signed char. This is what really screws up a lot of code.
> I do know the strict aliasing rules quite well.
Not well enough, if you think what you wrote above ("memcpy or malloc cannot legally be written in C without breaking this behavior") is true.
> Also not true.
You cannot implement malloc in C because malloc always returns a pointer that's not a part of an existing allocation. The malloc in libc has special dispensation from the compiler to do this (GCC "malloc" attribute).
Similarly you can't implement pthread mutexes in C because they imply optimization barriers (all global memory might change) that a C function with a visible implementation wouldn't have.
C11 has atomics and all the necessary primitives, fences, locking, etc..., to implement pthread_mutex, including its own mutex.
You know of course there is a trade-off between the possibility of optimization and strict compliance to a standard with zero or very little undefined behavior.
It's wrong to say C is "lost" because of these characteristics. It might not be a good fit for what you want to do, then use whatever you think is best. Just as Rust might be better than C for some cases, the reverse is true for others.
> This eliminates common null pointer checks but also breaks some non-conforming code-bases (such as Qt-5, Chromium, KDevelop)
I also use the features of modern C/C++ compilers such as warnings (-Weverything on clang, then turn off those warnings I'm not interested in) and sanitizers (Undefined Behavior Sanitizer, Address Sanitizer).
Undefined behaviour allows the compiler writer to have the code do anything unreliable and unpredictable and not document it. Its purpose is to allow compiler writers to completely ignore the erroneous code that results in UB and not spend effort trying to diagnose it or implement it. Most compilers still make an effort to diagnose some UB anyway, though.