11 ms·
Final features of C++17
- quotemstr 10y agoYet memcpy(0, 0, 0) is still undefined behavior? For shame.
- vardump 10y agoPlease read the edit below. This case has a very subtly trap. ------ Old comment: Makes sense it's undefined behavior, because address 0 is involved. Although I'd guess compiler implementations might just drop whole statement, because length is 0. Zero length memory copy is a no-op. Just like static zero iteration loop. They become zero instructions. (Except of course initialization that affects something outside loop scope.) Edit: Changed my mind after learning about the tricky UB pathway: If compiler can statically prove memcpy length argument to be zero, it can ALSO prove both argument pointers to be not NULL! Ouch!
- Rarebox 10y agomemcpy(0x1, 0x1, 0) is a well-defined no-op even when you don't have 0x1 in your address space. Why handle 0x0 differently?
- vardump 10y agoWell, just before I just saw a "read" and a "write" to address 0. Not as mechanism that can cause serious bugs, when the compiler can statically prove length argument to be 0 and you can have NULL arguments as input. Calls to memcpy with zero length are definitely not uncommon. Macros are an obvious way, but it's worse. All you need is a data flow where compiler can statically prove that all paths lead to zero length argument. I have to agree it's very scary that memcpy(NULL, NULL, 0) is undefined.
- plorkyeran 10y agoPassing a non-null pointer that points outside your address space is made UB by the exact same sentence as the one that makes passing null UB.
- quotemstr 10y ago> memcpy(0x1, 0x1, 0) is a well-defined no-op Sure about that? It really should be a no-op. The C and C++ standards are seriously broken in this respect, and compiler authors take advantage of this brokenness to get away with miscompiling programs that, to anyone with common sense, are fine.
- quotemstr 10y agoIt makes absolutely no sense for this behavior to be undefined, and letting it be undefined behavior causes real problems. See https://www.imperialviolet.org/2016/06/26/nonnull.html https://www.imperialviolet.org/2016/06/26/nonnull.html The C and C++ standards must be changed to explicitly state that memory operations on zero bytes do nothing regardless of whether the inputs are valid pointers.
- vardump 10y agoOuch. Didn't think about that compilers can then assume passed pointers aren't NULL. And proceed to optimize your NULL checks away, because that memcpy would have been undefined behavior. It seems so obvious after reading that. Should always ask oneself "what can the compiler prove as a consequence of this undefined behavior?". So, you're right, memcpy(NULL, NULL, 0) should be defined as a no-op.
- quotemstr 10y agoSome of us been trying to highlight for a long time now how compilers are taking unjustifiable liberties with undefined behavior
- vardump 10y agoWell, undefined behavior is generally a good thing. It enables a lot of very reasonable optimizations. Zero-length memcpy pathway to UB is not obvious, because whether the whole thing is UB depends on whether compiler can statically prove the length to be zero. Ugh.
- quotemstr 10y agoI think the statically-prove-length-is-zero thing is a distraction. What do you think of memcpy(ptr1, ptr2, 1)? The compiler should be able to assume (legitimately, this time) that ptr1 and ptr2 are non-null. The problem isn't a special case for zero length: the problem is the lack of a special case for zero length.
- halayli 10y agomemcpy behavior is not part of C++ standard. The C++ standard is only concerned with formally defining the ability to use it and the header name to include.
- vardump 10y agoStrictly interpreting true, but grandparent's point is very valid. It's used everywhere in real life C++ code. quotemstr got a very good point and I'm grateful for the heads up.
- halayli 10y agobut memcpy outside the C++ scope is what I meant. The C++ committee cannot do much about memcpy but they can introduce a new memcpy with a different name that has better ub support.
- Kristine1975 10y agoThe C++ committee can and does change how functions of the C standard library work in C++, see Appendix C of the C++ Standard (granted, most of those changes simply specify how the library functions interact with C++ features). C++ is not 100% compatible with C.
- smitherfield 10y agoBut the C++ standard could, without any changes to C, be amended to formally define which assumptions the compiler may or may not make about the C API in certain edge cases, such as memcpy(0,0,0).
- halayli 10y agomemcpy is outside the territory of C++. it doesn't fall under the language specification. it's as simple as that. If they go this route what stops them from defining assumptions to system calls?
- setra 10y agoIt will be great to see variants as a standard part of the language. Variants provide a way of doing a sort of type safe union for different types of data.
- quotemstr 10y agoThe new variant feature is based on boost::variant, which you can use today. Getting the thing into the standard library is nice and all, but it doesn't open up new capabilities the way that new syntax does.
- hellofunk 10y agoThe implementation of variant in C++17 is very different than in Boost. The Boost variant has a double buffer for the entire variant, and one of these buffers is always kept on the heap even if your variant is on the stack! This acts as a safety net incase the changing of the variant's value were to throw, you can get the old value back. This implementation did not fly for C++'s goal of being high performance, and thus the new standardized variant is done quite differently.
- n00b101 10y agoI did not have a good experience with boost::variant ... Compile times increased drastically, compiler error messages became enormous and garbled with templates, syntax was onerous in places (e.g. "make_recursive_variant"), and identification of types is based on arbitrary index value that is risky to rely on (which() method). I ended up refactoring the whole thing, removing boost::variant and just using the traditional visitor pattern. The only advantage boost::variant really has over traditional C++ visitor pattern is that boost static_visitor functions can have a non-void return type ... Being able to directly return a value in the visitor functions is admittedly very convenient, but the other issues negate this convenience.
- meetingcpp 10y agoboost::variant is 12 years old, the std::variant version is not based on the actual design nor is it a copy of the boost implementation. The interface is very similar, but the implementation is ofc using C++17 and not C++03.
- agumonkey 10y agoVariant, destructuring, template auto.
- lorenzhs 10y agoconstexpr if seems pretty neat, previously you could do things like constexpr bool foo = /* some constexpr */, this makes it a bit easier and saves a line. Structured bindings seem like one of those things that was just forgotten in previous standards, I'm glad it's here now. The syntax is a matter of taste, I guess. I'm also quite excited about variants, they probably won't be used much but sometimes they're just what one needs. Having them without requiring boost is nice.
- leni536 10y agoCan't you declare a bool as constexpr in C++14 (and maybe in 11)?
- lorenzhs 10y agoEh yeah of course you can, I updated my comment. Thanks.
- toth 10y agoI agree that constexpr if looks great. I am confused about the decision on how to handle static_assert. It seems that if constexpr (false) { static_assert(false); } Will fail to compile because the static_assert will trigger. This seems strange to me, anybody have an idea what the reasoning here is?
- lorenzhs 10y agoI think it's only consistent. Static assertions should always always always hold (things like type checks etc), if you really want to only evaluate it in that branch you can still do if constexpr (foo) { static_assert(!foo || /* assertion */); } else { static_assert(foo || /* assertion */); } (this gets ugly fast with lots of else-ifs, but it's a workaround - I don't know why you'd ever need it, though)
- toth 10y agoHmm, it seems this constexpr if is much more limited than I realized then. If I understood correctly the code in the the body of the constexpr if has to be correct even if the condition does not hold. I.e., this code: template<typename T> void func(T x) { if constexpr ( std::is_same< T, ClassWithMemberF>::value ) { x.f(); } } will not work if you pass in a type for x that does not have a member function f. Is my understanding right? If so, constexpr if is not nearly as nice as I thought...
- BinaryIdiot 10y agoI'm very disappointed the networking ts wasn't included (I must have missed when that stopped being a C++ 17 thing). It's one of the few things missing that would let me use C++ for more projects (yes I know I can just include the boost library since that's essentially what it'll be but that's not always the easiest thing to grab and build into an existing project (at least not for a C++ novice like myself) but being part of the standard will make it immensely more accessible). At least it still exists much like some of the other ones like the filesystem ts. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4588.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n458...
- quotemstr 10y agoI'm not sure that you should be writing network code in C++ (which is a notorious source of nasty security bugs) if you're not comfortable enough with C++ to link against one of its most popular freely-available libraries. I'd rather the committee focus on longstanding language core issues than add everyone's favorite library.
- jokoon 10y agoIf you're in video game or embedded system, it's a different story. Libraries are fine, but the problem here might be about OS or platform.
- EpicEng 10y agoI had to write a plug in that makes a REST call a couple of weeks ago. This thing was ~200 LOC max and I had to link to a library that is orders of magnitude larger just to make an HTTP call. I would have loved some standard networking functionality in that instance.
- nambit 10y agohttps://github.com/mrtazz/restclient-cpp https://github.com/mrtazz/restclient-cpp ? 2 LOC. Wraps libcurl.
- KKKKkkkk1 10y agoI'm a bit frightened with the move toward adding a compile-time sublanguage. Frightened because I feel it will end up being half-baked and then abandoned like other C++ features (virtual inheritance for example). As an example, I've been exploring Sean Parent's idea of concept-based polymorphism that allows you to implement "virtual functions" that get bound at compile time. To make this scheme explicit, I need to assert in the base class that all my "derived" classes implement a method with a certain signature. Does C++ allow me to do this?
- quotemstr 10y ago> adding a compile-time sublanguage. The C++ template system is already a Turing-complete functional programming language and has been since C++'s inception. I see nothing wrong with making this language's syntax more convenient. > half-baked and then abandoned like other C++ features (virtual inheritance for example) Virtual inheritance has its place. It's part of the language and works fine. What would you change?
- deleted 10y ago[deleted]
- vvanders 10y agoVirtual inheritance means you have a diamond pattern and haven't separated your components properly. It should have never made it into the language as far as I'm concerned.
- quotemstr 10y agoThat's a matter of taste; opinions differ. One perhaps less controversial case for virtual inheritance is in exceptions: see http://www.boost.org/doc/libs/1_53_0/libs/exception/doc/using_virtual_inheritance_in_exception_types.html http://www.boost.org/doc/libs/1_53_0/libs/exception/doc/usin...
- ioquatix 10y agoIt's useful for interfaces, e.g. virtual public IFoo, is it not?
- vvanders 10y agoReally looking forward to auto templates, so annoying to have to specify type signatures in lambdas when most other languages don't require it.
- Kristine1975 10y agoLambdas support that in C++14 (generic lambdas/polymorphic lambdas).
- vvanders 10y agoAh shoot, you're right. Not sure how I got them confused.
- jokoon 10y agoSo the next standard will be in 2020 ? I hope I will manage to try modules in MSVC before that time.
- Kristine1975 10y agoThat seems to be the plan: https://isocpp.org/std/status https://isocpp.org/std/status
- corysama 10y agohttp://cppcast.com http://cppcast.com just had a great interview with Herb Sutter where he talked about many of these features. http://cppcast.com/2016/06/herb-sutter/ http://cppcast.com/2016/06/herb-sutter/
- ranit 10y agoThe link is right there in the first paragraph :-)
- vardump 10y agoI'm always happier the more I see old cruft removed in a new C++ standard. Trigraphs [1] are gone. Good riddance, they're just used for pointless pranks anyways. Otherwise they just seem to cause issues, there's always someone who didn't know about them at all. Also "unexpected_ownership_move" err... "auto_ptr" is gone [2]. Yeah, I know, there's nothing inherently wrong with it and you knew how to use it correctly... [1]: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3981.html http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n398... [2]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4190.htm http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n419...
- quotemstr 10y agoRemoving these facilities is a stunt. Real compilers will have to support them for decades (maybe at least auto_ptr) anyway, so there's no sense deleting them from the standard. It's sufficient to just recommend against their use.
- klodolph 10y agoI wouldn't say it's just a stunt. While they will remain supported, their removal from the standard can be cited by engineers for political support to modernize code bases. Compilers also support strict compilation modes which remove obsolete functions, to help modernize your code base. This is all facilitated by removal from the standard. This also makes the standard smaller.
- EpicEng 10y ago>While they will remain supported, their removal from the standard can be cited by engineers for political support to modernize code bases Man... Who do you work for? If I used that as a reason for a refactoring my boss would laugh at me (and he's technical) . I imagine his boss would glaze over for a bit and then ask him to leave his office.
- klodolph 10y ago
- cm3 10y agoModules didn't make it in but are arguably top of the list of practical improvements for everyone and considering the time it will take to trickle down to toolchains and build scripts.
- squidbidness 10y agoTo clarify a question raised in this write-up: "auto [a , b , c] = getvalues(); "The braces are needed, getvalues returns a tuple. std::pair is not mentioned in the proposal, so its unclear if this works with pair, which is returned by the STL in some insert methods." Destructured bindings will work with arrays; plain aggregate structs; and any class that offers a specialization of std::get<>(), so both std::tuple and std::pair are supported as a consequence. (C++11 added std::get<>() for std::pair).
- ant6n 10y agoWhat if the number of lhs values don't match the number of rhs values?
- Kristine1975 10y agoCompile-time error: Otherwise, if the expression std::tuple_size<E>::value is a well-formed integral constant expression, the number of elements in the identifier-list shall be equal to the value of that expression (E is the return type of "getvalues" in squidbidness's example, the initializer-list is "a, b, c".)