Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Won't this break stuff?


Maybe. For example, GCC 5 changed the default for C from gnu89 to gnu11 and that broke the build of some Finnish amateur project:

https://lkml.org/lkml/2014/10/19/94

That's why projects that use GCC or a compatible compiler should use the -std option to set the targeted standard and not rely on the default.


Pretty much. Taking the "will this break stuff?" worry to the logical extreme would mean that gcc should default to a pre-standarization K&R dialect and g++ to a cfront dialect contemporary with 1st edition Stroustrup.

The world moves on. Though if you're an active project, moving along with the world is probably a better option than throwing in --std=c++really-old and deliberately refusing to use new stuff.


Forcing the update of old code doesn't make me sad. Considering new versions of the language should be improvements over previous ones, it may be a good side effect. If your code breaks with the new compiler and language standard, just change your build options to explicitly use the previous one.


If you maintain one of the rare codebases that would break, then just add "--std=c++98" to your compiler flags.

GCC has already been getting steadily more strict by default, or at least opt-in with -Wall -Werror. The last time we updated our build environment, we had to go in and #include all the headers that were formerly implicit (or #include-d by other headers), and add in the 'const' every time we referred to a string literal. The possibly-unassigned variable checker also got a lot more sophisticated and now would enter called functions.


I've been lead to believe that gcc can't / won't add warnings to -Wall precisely because of all the codebases that have -Werror.


New versions of gcc routinely fail to compile Firefox out of the box. A good example was gcc 4.7's -Wunused-local-typedefs, which is part of -Wall. Local typedefs seem to be a common pattern in Firefox's generated C++ (for IDL bindings).


This is why I think static bug checking and compiling should be two different tools. There is no reason to fail a build which used to run, even if it has bugs.

Doing all those checks at build time is slowing the build down too.


Splitting static checks and compiling into separate tools will not prevent your builds from breaking when you update your tools if you have your build process deliberately configured to break whenever a new warning appears. GCC adding new warnings will not break your builds if you do not specifically ask for it to by using -Werror (or having your CI system reject any builds that produce warnings).

At least with clang, -Weverything is not measurably slower than no warnings at all on any vaguely realistic code base.


A CI server is totally different to downloading a tarball and trying to run it. Using -Wall and -Werror in that situation is a terrible annoyance.

With regard to speed, I just know that tcc is 10 times faster than gcc, and that makes a huge difference to me. Anything pointless is really irritating because I know how slow gcc is.


Then the issue is still with the app developers who ship a tgz with -Werror as the default.

(Also I'd much rather have fast binaries slowly compiled than the opposite)


Obviously the issue is with the app developers. That is why I am suggesting splitting static checking and compiling, so shit developers at least stand a chance of doing the right thing.

(I would rather a fast compiler until I am ready to release a final product and then swap. I probably do more cross compiling and creating custom toolchains than you.)


If we're worried about lousy developers being lousy, then I think we should do the absolute opposite and make -Wall the default.


It shouldn't. 99.5% of C++98 code is valid C++14. Code compiled as C++98 and code compiled as C++14, should also link.


So if my code is at least 200 lines long...

(I know, it doesn't work like that. 99.5% means syntax elements or some such, not lines of code. But it still works out the same in a medium-to-large code base; 99.5% compatibility breaks more than you expect.)


I maintain a project that compiles as both C++11 and C++03. One pain point is that the headers have changed between them: #include <tr1/memory> to #include <memory>. This is complicated further by libc++, which doesn't have <tr1/memory>.


That's fairly straightforward to work around, however.

I've used both autoconf and cmake to do functional testing of which headers are available, and then include the most recent available out of <memory>, <tr1/memory> and <boost/shared_ptr.hpp>, bringing them into a project::compat namespace to make the codebase not need to care which is in use, and the same for a number of other tr1/boost types now in C++11/14.

I'm now at the point where for some projects I've been able to strip out this entirely and just use the C++11 types directly.


That is relatively straightforward in the scope of a large project (and it's what I do as well), but stuff like this really makes it harder to share small-to-medium sized C++ libraries.

I don't understand why C++03 didn't just use the std:: namespace.


What about a preprocessor check based on the __cplusplus value? If it's 199711L, implement the C++03 defines, if not, implement the C++11 defines.


Unfortunately this doesn't handle the libc++ case, which needs #include <memory> even in C++03.

What I ended up doing is something like this:

    // Ensure that _LIBCPP_VERSION is defined if necessary
    #include <ciso646>

    #if defined(_LIBCPP_VERSION) || __cplusplus > 199711L
      // C++11 or libc++
      #include <memory>
      using std::shared_ptr;
    #else
     // C++03 or libstdc++
     #include <tr1/memory>
     using std::tr1::shared_ptr;
    #endif


A quick Google search suggests that this won't work unless you also check for the MSVC version - sigh:

http://stackoverflow.com/questions/14131454/visual-studio-20...


If we changed __cplusplus before implementing every single C++11 feature, the Internet would riot.


If you're exposing __cplusplus=199711L then you really ought to continue to support #include <tr1/memory> (i.e. C++03 style). As long as you do that there's no problem and the suggested thing should work.


VC++ never used <tr1/memory> in the first place. That was purely a libstdc++ thing, and not something that TR1 or any C++ standard ever said to do.


Yep. (TR1 was published after C++03, they're totally different things.) What we did with TR1 was actually very friendly to migration - we provided std::tr1::meow in <meow> (in 2008 SP1), then in 2010 we aliased that to std::meow as C++0x was being finalized, then in 2012 we switched the True Name to std::meow and made std::tr1::meow the alias for back-compat. At some point in the future we'll probably remove the tr1 aliases completely.

For the Technical Specifications, we're following their header directory and namespace rules (<experimental/meow>).


Actually, I'm more interested in when a GCC with this patch will be marked stable by one of the distros that I use.


That's probably the reason why C++11 wasn't ever the default. Though, there are arguments about trying to be backwards compatible forever.

My personal opinion is to leave it the way it is - or at the very least default to C++11 first.


C++14 didn't introduce any new breaking changes to pre-C++11 functionality, so switching to C++11 first would not make the migration now any easier and would introduce the need for another migration in the future.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: