As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I've done a fair amount of programming in C/C++ before, but nowadays it only accounts for a small percentage of the programming I do (scripting languages are much better suited for a lot of the work I do). I worked on some C programming projects the last few days and was surprised how many little syntactical details I kept forgetting. What's worse is that cc/gcc typically had cryptic or non-informative error messages about these issues (sorry I can't remember any specific examples).
I learned about the clang compiler not too long ago and decided to try that. The error messages were much clearer and helped me identify and fix the problems in my syntax. My question is why this tool is not used/mentioned more than it is? Is it that it is so new compared to the usual suspects (cc/gcc), or is it that it doesn't support features that they support, or is it just harder to obtain? I have a hard time believing that last one, since it was installed with the dev tools on my iMac and required a single command (sudo apt-get install clang) to install on my Ubuntu box.
My question is why this tool is not used/mentioned more than it is?
It's probably because of history, and because how we humans generally behave.
Traditionally gcc has been the only real (free) compiler that can be practically used to compile C programs on atleast all the free *nix clones out there. It's what virtually all the base system and kernel of linux, *BSD, now probably OSX, and others are compiled with.
While flaws are here and there, basically this means: gcc works. And if it isn't broken, don't fix it. Out of this, you now have a huge user base, it's easy to get help with gcc, there's a lot of people that have used gcc, that are working on gcc itself etc.
Generally, if you want to switch a huge community from something they're used to, to something else, that "something else" have to be *significantly" better. Just "better" is often not reason enough. I think you can find examples of this in many areas of society.
clang is newer, some people will just be suspicious if it's up to the task, if it has bugs, if it produces slower code etc. - it seems to be in the human nature to be suspicious - new things are scary. Many don't even know about clang, many don't care because they're happy with gcc.
Though, if you rather want to use clang, go for it - error messages are indeed "better" and easier to understand vs gcc.
The clang front end is relatively new. For example, the 2.8 release in October 2010 marks the completion of the C++ 98/03 support.
It seems likely that with increasing maturity, there will be an increasing adoption. For example, there is ongoing work on making the FreeBSD OS (and other BSD OS's) build with clang, eliminating a dependence on GCC/G++.
Apple are pushing the LLVM/clang combination. It seems likely that they will cease to support their old GCC toolchain branch (based on 4.2) and come to depend solely on clang tools for OSX/iOS development.
Clang is also seeing increasing adoption in custom compilers for C-like languages (e.g. shader language compilers for OpenCL)
LLVM has been around for a while, but — at least in my neck of the woods — it has only risen to prominence very recently, possibly due to the fact that Apple has been pushing heavily of late to replace gcc with Clang in their own tool-chain.
Also, I believe it's C++ support has only recently become production-grade. EDIT: It appears that it isn't even that yet. (See comments below.)
Another factor might be that LLVM is largely backed by a single vendor, towards which non-Apple developers have an innate mistrust.
My question is why this tool is not used/mentioned more than it is? Is it that it is so new compared to the usual suspects…
This is exactly the reason. It is still new and core functionality is still being actively developed. Remember that existing projects may be making use of compiler-specific features – or using libraries which do – and developers are, in any case, loath to change working tools for experimental ones that may have unexpected bugs or unknown performance/size/etc. tradeoffs, even when the new tools are increasingly getting better every day.
As a student programmer I find it a total godsend mainly due to it's helpful and understandable error messages. I use it mainly for programming in C, though I am beginning to branch out into C++ also using Clang.
As to why is it not mentioned more, I suspect it is since GCC has been established for so long, for most users it is THE compiler. GCC for me works fine except for it's extremely cryptic error messages which as a student does throw me off quite a bit.
Overall I do highly recommend Clang for use by both students and developers. Since it is now the official compiler for Apple and Xcode, I suspect it's use and name recognition will quickly pickup. FreeBSD seems to have also adopted it as their main compiler though I suspect that will have less impact on it's popularity than it's adoption by Apple.
Addendum: Due to the competition from Clang, the clarity of the error messages in GCC 4.8 and 4.9 has shown a significant improvement; though I still find Clang a little more lucid, the gap however has narrowed significantly.
Today, clang is replacing gcc in most places. i.e., most *NIX-like operating system and Linux distributions. Some examples oare FreeBSD,Minix and mac(a bit obvious) clang that switched clang as default compiler. Some of my friends too,when I showed them.
This IMHO, looks like some peoples had problems with it,probably in older versions. But with clang version 3.0, I don't have any of this problems. As I metioned before, I'm using it really in all my new projects. Almost my default compiler, sometimes I do make C=gcc just to seen how difference to clang error/warning. And clang win ever. With better explanations and make a great effort to optimization. It include suggestions for use extensions(some are gcc inerhid) of the compiler to a best perfomance in the code generation.
I had written a trivial function that print an error message. But I would to exit from program after printed the error message on standard output. So,I make a simple modification,put an exit(1) as last statement in the function. As the following:
void error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "error: ");
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(1);
}
And so the clang show
warning: function 'error' could be declared with attribute 'noreturn'
[-Wmissing-noreturn]`
(gcc doesn't produce it even not with -Wall -Wextra -Wunreachable-code -O3 flags)
I say "that seems like nice. But what is 'nonreturn' attribute? I'd never listen or read about this. I jump to google and search for clang could be declared with attribute 'noreturn' (oh,yeah,I could just written clang nonreturn attribute,but forget it) and I found this link with a good explanation of what it this attribute and the possible gain of perfomance that I could get.
So I run to add this attribute to my function prototype(of course,if it is the gcc or clang compiler; macros will do the trick-detection). Oh yeah,to me,any small gain of perfomance(of course,without making the code unreadable) it a win.
And don't ends here,some year ago,I make return in a function where the proviously is a switch as default handling defined(as in the error() function here). But even so, gcc clains about function without return-value(I'm sorry,I don't recall to exactly error/warning message) how it possible? there is no more statements after switch,if no case match,default value is executed and don't really matter the below statements,if any. But clang think different,like me,and give a warning about this declaration,helping me make better code.
And for this kind of very small thing, I'm loving the clang.
(Note: I'm sorry for my bad english. English isn't my native language speaker, but despite it I'm trying express me here)
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I am a student and I am currently taking a compiler construction course. I develop my compiler in C++ on Ubuntu, using GCC and CMake. While everything works fine on my development machine, the code broke horribly when compiled against MSVC or Visual Studio 2017 on the school test. As I tracked down the error messages thrown by MSVC, I noticed there are several issues causing these failures:
GCC's headers give you more stuffs than MSVC does.
Some other weird errors that I can't explain (Sorry but I can find a better word).
To ground the discussion, see the following examples,
which work for GCC but break on MSVC.
#include <iostream>
int main() {
std::string S;
std::getline(std::cin, S);
}
MSVC requires #include <string> to work.
#include <unordered_map>
int main() {
std::min(1, 2);
}
MSVC requires #include <algorithm> to work.
These issues are not hard to fix once they break out: I can just #include the required headers. However, it is too expensive to let them break out. It takes away my scores and hurt me.
I have no interest in discussing which compiler is more standard-compliant. I simply want to catch any portability issue before they catch me. But I am not well-informed of all those tricky differences between these compilers. That's why I am asking for tools to catch these issues. I want to update my tool chains to write more portable code.
Edit: Besides tools, I will humbly learn any code disciplines, good practices and known issues in writing portable code.
Edit: Sorry folks. I am not meant to make the second example wrong (just deleted). I just have no access to a MSVC to reproduce the problems.
Edit for Clarification: What this post is not for:
How to fix certain issues when porting code from GCC to MSVC.
How to write standard-compliant C++ code that universally compiles.
In fact, this post is asking for practical actions one can take to port code from GCC to MSVC or better, to write code without portability issues from the beginning. The examples in this post are used to make discussion concrete or to show the actual difficulty, but not comprehensive. I don't think there is a single truth about this question, but I'd like to try out some good ones.
Compile against multiple compilers
When comes to portability there are two approaches. One charming, idealistic but non-practical: where you wish to write code that is absolutely portable: i.e. to work as expected on any compiler, real or imaginary, present and future. You might be tempted to say: hey that's just standard C++ code. Unfortunately compilers are software and as any complex software they have bugs. Moreover, the standard has bugs (where defect-reports are applied retroactively). The more you write complex code the more you will encounter these bugs.
The other approach is a practical one. Instead of aiming for 100% portable code, you aim for portability on a set of versions of compilers on a set of architectures. For instance you can aim for your code to work on x64 linux and windows, gcc clang and msvc, latest version , or from version x upwards and ignore everything else. (icc be damned). To achieve this there is really just one way: test your code on all these platforms. For this at minimum you need to create unit tests for your code and then compile and run these tests on all the architectures and compilers. You can do this manually or automate the process (e.g. CI).
Running your code on multiple compilers you will find that you need to modify the code to be more standard compliant or write different code for different compilers and versions to go around bugs or limitations. SO is full with compliant code that doesn't work on some major compiler (version) or another.
Compile with appropriate switches
Compilers have custom extensions (some enabled by default). You should disable them. It's compiler specific. For gcc and clang for example you need -pedantic. I don't know for msvc. But even these are not enough:
Some users try to use -Wpedantic to check programs for strict ISO C
conformance. They soon find that it does not do quite what they want:
it finds some non-ISO practices, but not all—only those for which ISO
C requires a diagnostic, and some others for which diagnostics have
been
Use tools complementary to compilers
Use static analyzer tools. These tools analyze your code and catch some cases of bugs, illegal or Undefined Behavior code.
Also take a look over clang sanitizers.
Don't forget about the standard
You say you are not interested in a discussion about which one is more standard compliant, but you should at least be interested in standard compliant code. For instance in your first example even if it happens to work on your version of gcc the code is illegal because including <string> and <algorithm> is mandated by the standard here.
When you encounter code that works differently on different compilers you definitely should investigate and see what is standard compliant.
I have a C++ soft that gets compiled with different OSes, platforms & compilers. Now sometimes compiler have bugs e.g. for instance this one, which implies that gcc versions pre 4.6.4 and pre 4.7.3 are a no-go. Now i could include a unit test that showcases the bug (and perhaps this question will reveal that indeed that's what I should be doing) but this is a tedious task: compiler bugs are sometimes hard to repro and turning one into a unit test might not be easy either... and that's when you have the platform & compiler at hand.
What I'm looking for is a repository that tells me which versions of g++, clang++ and msvc++ suffers from fatal bugs for supporting C++11 (i'm not talking about missing features, when features are not there I work around them). I would then fatal crash when building with them in the build system. Nice feature is, I'm not even forced to hit a bug to ban a compiler (so I'm saving myself future trouble).
Does such a list exist?
This is probably not the answer you are looking for, but I believe the correct way to deal with this is to have a white-list, rather than a black-list. In other words, have a list of compilers that you know works, and if the customer tries to build using a different version than the ones you have tested with, you issue a warning message as part of the build script saying something like this:
This compiler is not supported, please see
http://www.example.com/list_of_supported_compilers.html for a list of
compilers we support. If you choose to continue using this compiler,
feel free to do so, but don't expect full support from our
tech-support, if you find a problem.
The reason I say this is that:
You will not be able to prove that EVERY version other than what is on your blacklist works correctly. You can, however, for whatever testcases you have, prove that compiler X version a.b.c-d works [this doesn't mean that this compiler is bug free - just that you haven't hit any of those bugs in your testing!]
Even if the compiler is "known good" (by whatever standard that is defined), your particular code may trigger bugs that affect your code.
Any sufficiently large software (or hardware) product will have bugs. You can only show that your software works by testing it. Relying on external "there is known bug in version such and such of compiler X" will not help you avoid bugs affecting your code. Having said that, most compilers are fairly well tested, so you (usually) need to do some fairly unusual/complicated things to make the compiler fail.
Investigate Boost.Config, in particular the header <boost/config.hpp>.
This includes a large group of macros for a wide variety of compilers (and different versions there of) which indicate which C++ features are enabled, broken etc. It also includes a comprehensive test suite which can be used to test any new compiler for missing features etc.
I've found an odd inconsistency between Rcpp which compiled with and without -std=c++0x.
Consider the expression
Function data_frame("data.frame");
GenericVector a;
a.push_back("17");
return data_frame(a, _["stringsAsFactors"]=0);
(ed. note: coercion to DataFrame in Rcpp actually thunks down to the R function, but doesn't allow the user to set that flag.)
In "old" C++ (w/o -std=c++0x set) this code works. In modern C++ (w/ -std=c++0x set), this fails, saying "cannot coerce class "pairlist" into a data.frame".
Obviously, this isn't the end of the world: I just don't use any newer features. However, I confess to being totally at a loss as to what causes this difference, and how to work around it without throwing C++11 away. Any ideas, anyone?
Code targetting features of the new standard was written in Rcpp about 2 years ago.
But then, later we realized that CRAN did not accept the -std=c++0x flag for gcc (or equivalent flags for other compilers), and forcing the C++99 standard and therefore we cannot realistically use it.
Consequently we pretty much don't maintain the C++11 aware code. That's a shame because we'd really like to, but we prefer the exposure of being accepted in CRAN. Since we don't maintain, there are probably many things that don't work as they should.
This particular issue is probably easy to fix. And this will happen as soon as we get the green light on using C++11.
We love C++11 and cannot wait to use it. But we cannot use it in uploads to CRAN (as per a decree of the CRAN maintainers who consider C++11 "non portable" at this point -- please complain to them, not us, of that irks you).
Consequently it is currently "barred". There is a bit of detection in RcppCommon.h and we define HAS_CXX0X. But we haven't really written code for this, as we can't (yet) per the previous paragraph.
So if you found a bug, please do us the favor and report it where request follow-ups to be sent: the rcpp-devel list. Reproducible is good, patches even better :)
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
There're several new c++ guys working in our team, so too much ugly code everyday!
I hate those functions using readonly string, STL containers as parameters in, but without const reference!!! I'm crazy!!!
Is there any static code checker that can find these ugly code? I need such a tool used in our makefile.
Yeah, it's unlikely that "bad code" can be prevented with automated tools.
For myself, and I'm also doing this at my workplace, I've always turned on as many warnings as possible (usually by enabling a high level of warnings and only turning off the 'obviously dumb' warnings; g++ being the only exception since it doesn't have an option to turn on everything, so I do -Wall, -Wextra and a whole bunch of other -W, and occasionally go through the manual to see whether new warnings have been added).
I also compile with -Werror or /WX. Unfortunately, while Linux and Windows headers seem to be rather clean by now, I get stupid warnings about things like bad casts or incorractly used macros from boost headers. 3rd party libraries are often badly written wrt to warnings.
As for static analysis tools, I did try cppcheck and clang (both of which are free, which is why I tried them). Wasn't thrilled about either of them; I'm still planning to add some support for one or both to my build software, but it has rather low priority. One of the two (don't remember which one) actually found SOMETHING: an unnecessary assignment, which any decent optimizer will remove anyway. I don't think that I'm such a perfect 0-bugs developer, so I'm blaming the tools. Still, I did remove that assignment :-)
If I'm not mistaken, the commercial VisualStudio versions have code analysis as well (At home I'm more of an Express guy, and I'm stuck with MacOS development at work); maybe that one is better. Or one of the other commercial tools; they have to offer SOMETHING for their money, after all.
There are still some additional free tools that I haven't tried yet; I have no idea how complete the http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#C.2FC.2B.2B list, but I hope to eventually try all the free tools that can handle C++.
For your problem in particular, Wi8kipedia describes "cpplint" as "cpplint implements what Google considers to be "best practices" in C++ coding". I have no idea what that means, but the Wikipedia page has a link to a "Google C++ Style Guide" pdf. Or you could just try it and see what it complains about :-)
Also, I probably wouldn't want to add such tools to the Makefile (unless you meant to imply that people still have to invoke "make check" to actually run it). Adding it to the source code repository to check new commits before allowing them is probably too time consuming (code analysis is pretty much "compiling with many extras", so it takes a good deal of time), but you could automatically run it every now and then.
parfait or lint, google "Static Analysis Tools"
You could probably pick up some of these by using the -Wall flag if you are using GCC to get these as warnings.
Of late I'm facing the issues that points finger to VC6 compiler.
Few of them are:
A function-try-block doesn't work. Related Q
in-class constant doesn't work.
__FUNCTION_ (Macro to get function name) doesn't work
The latest addition is it doesn't allow void functions to be passed as part of for_each.
The below example is not compiling with VC6 compiler. It says "error C2562: '()' : 'void' function returning a value". It looks like VC6 doesn't like void functions to be passed to for_each.
class Temp
{
public:
Temp(int i):m_ii(i)
{}
int getI() const
{
return m_ii;
}
void printWithVoid()
{
cout<< "i = "<<m_ii<<endl;
}
bool printWithBool()
{
cout<< "i = "<<m_ii<<endl;
return true;
}
private:
int m_ii;
};
int main(void)
{
std::vector<Temp> arrTempObjects;
arrTempObjects.push_back(Temp(0));
arrTempObjects.push_back(Temp(2));
//Doesnot work, compiler error
std::for_each(arrTempObjects.begin(), arrTempObjects.end(), std::mem_fun_ref(&Temp::printWithVoid));
//Works
std::for_each(arrTempObjects.begin(), arrTempObjects.end(), std::mem_fun_ref(&Temp::printWithBool));
return 0;
}
Have you faced any other issues related to VC6.0. Any workaround to resolve these issues ? Or is it time to change the compiler?
Quite frankly I can hardly understand why you wouldn't buy a modern computer and switch to Visual Studio 2008.
VC6 has got a deficient STL, poor C++ standard compliance and obsolete GUI.
You shouldn't let your competitors use better tools than you.
Well, here's the thing. The VC6 compiler sucks. However... the IDE is pretty good.
VS2005 has much better source control support. Otherwise, it's much slower debugging, has a crappy output pane that exponentially decays on inserting output lines (what absolute garbage coding is that?), the help system is many times slower, and debug and continue (possibly Microsoft's best feature over other IDEs) is considerably more broken.
.NET? Sure, VS20xx is the only way to go. However, for one small client that is sticking with VC6/MFC (for interfaces to embedded systems, etc) I actually enjoy working with VC6. It's just FAST.
2008? I'd like to... but it takes a while for my clients to migrate. Nobody has, yet.
Is it time to say goodbye to VC6
compiler ?
Yes.
VC6 cannot do much of any kind of modern C++. I recall I tried to use one of the boost libraries ages ago like probably Graph and it was giving "INTERNAL COMPILER ERROR" all over the place so eventually I chucked that in.
The no-brainer answer is yes, and ASAP. You have free alternatives like VC++ express and Code::Blocks, if the cost as in issue. The pain in solving compatibility issues is IMO no reason not to upgrade because you will have to do it some day anyway and it only gets harder.
The only reason I see for a possible obstacle is if you have MFC code that will be difficult/time consuming to port. In that case you can't use VC++ express (no support for MFC) and you have to make the investment for at least the VS std. edition. That will cost you about EUR 300 (depending on where you live).
I changed from VC++ 6.0 to Code::Blocks (which is FOSS) with g++ a few months ago and haven't really looked back. I miss the VC++ debugger a bit, as the gdb implementation in CB is nowhere near as slick, but that's about all. Some things in the IDE work better (code completion, tooltips, dependancy xalculation) and the compiler is obviously much better.
Regarding your points, function try blocks are hardly a widely used feature, and most people think they are pretty useless. And the __FUNCTION__ macro is not part of the C++ Standard, so you shouldn't depend on it too much if portability is an issue.
No, it was time to say goodbye to it a decade ago. Here are a few reasons why:
There are free, standards-compliant compilers available, both from Microsoft and others
VC6 was written before the C++ language was standardized, and it is nowhere near standards compliant. Especially templates and the standard library live in a world of their own, with no tie to how these features actually work in ISO C++. The language it compiles is not C++. It is a hybrid of pre-standard C++, Microsoft extensions, compiler limitations and bugs. Neither of which are desirable.
VC6 is known to generate invalid code in some cases. Not only does it compile a home-made, buggy and nonstandard language, it also makes invalid optimizations causing crashes, or in some cases actually produces bad assembly that simply can not be executed.
It is broken, and it was always broken. It was designed to compile a language that ceased existing about the same time as the compiler was relased (when the language was standardized), and it failed even at that task, with countless bugs, some of which have been fixed in the half-dozen service packs that were released. But not all of them, and not even all the critical ones.
Of course, the downside to this is that your application is most likely just as broken. (not because you're bad programmers, but because it targets a broken compiler. It has to be broken to be accepted by VC6)
Porting that to a standards-compliant compiler is likely to be a lot of work. Don't assume that you can just import your old projects, click "build", and it'll work.
So if you're part of a big business that can't just take a month off to switch compilers, you might have to port it as a side project, while part of the team is maintaining the VC6 version. Don't scrap VC6 until you've successfully ported everything, and it works.
Unless you have a large program to maintain, yes. Switch today!
The Express versions of VC++ are a free download from Microsoft.
I guess this is why so many applications on Windows sucks because people still use VC6. Why mess with broke, never maintained MFC or even Win32 when their is wxWidgets and Qt4 out there way better than MFC could ever be and you you can even use the free additions of Visual Studio 2005+
You can learn to live with VC6s foibles. It almost has a certain retro charm these days. We've been repeatedly providing "just one last VC6 release" of some libraries to a customer for years now. Hard to argue with a customer prepared to pay for the extra work backporting and maintaining a branch. But at some point the cost for us to backport newer features developed in newer VCs will exceed the cost of them upgrading at their end (especially as more boost and Intel TBB creeps into the codebase's head). Or at least I hope that's what'll happen! Worst case it'll happen just as flaky C++0x support appears and we'll be stuck supporting that for them for 10 years...
General rule seems to be that a new version is an upgrade and is thus worthwhile.
However! you have to pick the right time for it, there are so many bugs fixed, but you then need to be aware of the new bugs and variations from the standard.
Set aside time for the upgrade.
Upgrading compiler versions could well be a project in its own right, make sure you have stable code and good tests before you do an upgrade and when you finish prove that it is still working the same.
You may be forced to upgrade when you start to develop for Vista as VC6 doesn't provide for code signing easily and the redist is not in a form that Vista likes. (want at least VC2K5)
Are you updating the OS any time soon? When I researched moving our apps to Vista, I found that Vista doesn't officially support anything before VS 2005 (except for VB 6), and has a page-long list of possible little problems with VS 2005 that may or may not bite you. I recommended delaying until VS 2008 SP1 was available (i.e., when VS 2008 was really usable), and doing the compiler changeover first.
If the project is a special one for a few customers who run it soley on old NT machines, you may want to keep it at VS 6. If you are selling it for any sort of general consumption, you will need to make it Vista-compatible at some point (or 7-compatible, or whatever), and you will need to upgrade.