108 karma · joined November 17, 2012
test.cpp:16:45: error: Using object that is a temporary. [danglingTemporaryLifetime]
assert((std::vector<int>{1, 2, 3, 4} == append34({1, 2}))); // FAIL: UB
^
test.cpp:3:12: note: Return lambda.
return [&](std::vector<int>&& items) {
^
test.cpp:2:50: note: Passed to reference.
auto make_appender(std::vector<int> const& suffix) {
^
test.cpp:4:36: note: Lambda captures variable by reference here.
return append(move(items), suffix);
^
test.cpp:15:35: note: Passed to 'make_appender'.
auto append34 = make_appender({3, 4});
^
test.cpp:15:35: note: Temporary created here.
auto append34 = make_appender({3, 4});
^
test.cpp:16:45: note: Using object that is a temporary.
assert((std::vector<int>{1, 2, 3, 4} == append34({1, 2}))); // FAIL: UB <source>:8:16: warning: passing a dangling pointer as argument [-Wlifetime]
std::cout << sv;
^
<source>:7:38: note: temporary was destroyed at the end of the full expression
std::string_view sv = s + "World\n";
^
And cppcheck will catch the second example: <source>:7:12: warning: Returning lambda that captures local variable 'x' that will be invalid when returning. [returnDanglingLifetime]
return [&]() { return *x; };
^
<source>:7:28: note: Lambda captures variable by reference here.
return [&]() { return *x; };
^
<source>:6:49: note: Variable created here.
std::function<int(void)> f(std::shared_ptr<int> x) {
^
<source>:7:12: note: Returning lambda that captures local variable 'x' that will be invalid when returning.
return [&]() { return *x; };
^
Cppcheck could probably catch all the examples, but it needs to be updated to understand the newer classes in C++.No it wasn't. Boost.Range library predates Andrei's Range talk in 2009. Boost.Range was introduced in boost 1.32, which was released in 2004:
https://www.boost.org/users/history/version_1_32_0.html
And from Boost.Range's "History and Acknowledgement" it explains where the term came from:
> The term Range was adopted because of paragraph 24.1/7 from the C++ standard
https://www.boost.org/doc/libs/1_32_0/libs/range/doc/history...
Furthermore, what is being standardized in C++ is an expansion of what is in Boost.Range, which uses iterators underneath.
Andrei's term for ranges(and what is in D) are actually quite different as it removes the basis for iterators completely.
https://m.youtube.com/watch?v=bsXLMQ6WgIk
Now, overriding a builtin function is not the best idea so in boost cmake modules we have a bcm_ignore_package function which will setup find_package to ignore the package :
http://bcm.readthedocs.io/en/latest/src/BCMIgnorePackage.htm...
In Java/C#, it doesn't always:
int x = 1; int y = 2; x = y;
The variable `x` does not refer to the object that `y` is referring to(as there is no reference involved at all).
Assignment is a procedure that makes `x` equal to `y` without modifying `y`. However, if `x` refers to `y`, then we can modify `y` after assignment to `x`. This destroys the ability to reason locally about the code, because each object essentially becomes as good as a global variable.
Even though C++ has areas where things gets complicated, this is the one thing that C++ keeps very simple and consistent. There is only one definition of copy, assignment, and equality, whereas in java there is multiple definitions(deep copy vs shallow copy, `==` vs `.equals`).
> That’s called value semantics, although I would prefer the term state semantics: objects do not have a value, they have state, and that’s what’s being transferred here.
No. Its value semantics, as these objects represent some entity. The interpretation of the state(or datum to be more precise) is the known as the object's value. For example, when copying a `std::vector` the internal state of the vector will be different on copy, as it will point to new piece of memory, however, its value will still be the same.
> But experience shows that making a copy of an object is hard.
The compiler already generates a copy constructor and assignment for you. Its only necessary to write one, when one is dealing with low-level pointers. Using the standard built-in types and containers, writing a copy constructor is never needed.
We want to steer away from standardizing a build system for now. The uses cases are enormous to try to tackle. Instead, it would be simpler to standardized the description of the build environment so the package manager can pass that to the build system.
Hopefully, build systems will be updated to read the package metadata so it can properly consume the dependencies correctly.
> So yes - I'm convinced a metadata file as you suggested is the way to go.
Good to know we are on the right track.
I believe buckaroo uses integrated builds so its likely you would need to supplement it with other information such as source files, but hopefully the core information could be reused.
That is mainly for binary distribution. Most C++ package managers currently are source-based because binary compatibility is not a easy problem(there are some package managers trying to solve it though).
> Unfortunately, it is still terribly easy to write non-portable code with C++
Yes, it easy to call into a platform-specific API, so cross-platform portability is limited by the testing resources for the package maintainer or library author.
The problem is extra work is needed to support things like cross compilation.
Instead, you want to pass a toolchain file that describes the build environment(including for cross-compilation) to the build system, and it will compile it correctly for the target. This is the way cmake works, but we should have standard toolchain file that can be used across all build systems instead of requiring everyone to use cmake.
Conan does this too. If I follow the instructions to integrate cmake with conan, I would write something like this:
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
add_executable(timer timer.cpp)
target_link_libraries(timer CONAN_PKG::Poco)
Which now couples my build with conan. If the user would like to pull down the dependencies without conan(ie using apt-get or manually installing them), the cmake build script will not work.Package managers like cget[1] or conda[2] does not couple the build with the package manager. Cget is also serverless which is nice as it can install dependencies from anywhere(even directly from github with `cget install jgm/cmark`), however, you need to setup your own server hosting if you want to install binaries.
That is the same technique that Stephanov describes in 'From Mathematics to Generic Programming'.
https://channel9.msdn.com/Events/GoingNative/2013/Inheritanc...
https://github.com/rtfd/recommonmark
However, commonmark currently lack support for tables, so I fall back on rst for tables(actually I think the syntax for tables in rst is much better than tables in other markdown flavors).
Also, resolving links using commonmark in sphinx is a mess, right now. I actually extended recommonmark so sphinx will properly resolve cross references(including reference to elements in a domain). However, I had to update sphinx as well, which I have a PR open with no response from them, here:
https://github.com/sphinx-doc/sphinx/pull/2644
It seems unfortunate that sphinx devs are unresponsive to contributions. The devs for mkdocs are a lot more responsive, but seem more interested in monetary contributions, unfortunately.
And in C++, it provides the same high-level expressiveness as in Python.
> the more you can use them to easily do complex things arcoss different domains quickly.
But the advantage of C++ is that those abstractions have almost no overhead.
> So, for example, Python may have a better algorithm
Actually, C++ has a complexity guarantee for all of its algorithms.
> but C++ may use the hardware more efficiently.
Well, the brilliance of what Stepanov did was to build general purpose algorithms with out taking away random access capabilities which is beneficial for hardware efficiency(even more so now with modern cpus).