Yea and C++ static analysis tools already warn for the case, so even for new C++ programmers where it might not be entirely obvious, its still easy to catch the error.
HN user
pfultz2
You dont need annotations, cppcheck already warns with:
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: UBConcepts specify constraints on templates, but the types are still templates, so you can't put the function definition in a .cpp file nor put them into a vector(which is what type erasure allows).
That seems more like type erasure as defined in Java where the container is the same for all data types and the compiler implicitly inserts casts from the base type to the parameter type.
But cppcheck can find a lot of dangling references with lambda captures.
Clang's lifetime profile will catch the first example:
<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++.Meson looks nice, but it still lacks a way to tell it where your dependencies are installed(like cmake’s CMAKE_PREFIX_PATH). You can try to get by, by setting pkg config path, but it doesn’t help for dependencies that don’t support pkgconfig.
For the sake of history, `range` was found/coined by Andrei
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.
Higher density may allow for more volume but it can increase viscosity.
Daniel Pfeffier’s effective cmake talks about how to do that. Setup each project standalone and get the dependencies with find_package. Then create a superprojects thats add each dependency with add_subdirectory and override find_package to be a no-op for dependencies added with add_subdirectory, since the “imported” target is already part of the build:
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...
What does that do? It makes the variable x refer to the object that y is referring to
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.
Currently there is no buildsystem that enables users to describe the requirements of an project correctly.
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.
The package managers that are listed in the post are cross-platform and work on windows.
Or rather, I would like to hear your opinion instead. Would buckaroo consider using a standard package metadata similar to what I outlined?
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.
I'm surprised the author forgot to consider platform architectures
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.
Wonder if Nix package manager would work here.
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.
You can't do that with United Airlines. The answers have to be picked from a drop-down of answers.
Last time I looked at Nix it had a problem with dealing with cross-compilation. The problem is mainly that many packages still use autotools which does not have a descriptive toolchain. Ultimately, it could provide a descriptive toolchain and then map that toolchain to the different build systems, which is similar to what cget does, but perhaps a separate tool to do this could be helpful so this could be shared among different package managers.
This sound similar to cmake-get:
pkg-config works on windows with visual studio as well.
Actually cget can install packages directly from cmake packages(or other build systems). There is also the cmake-get module which can install cget recipes directly in the cmake without needing cget or python installed.
The nice things about cget is that even though it uses python(which is mainly for easy distribution), the cget protocol only has a dependency on cmake. So cmake modulues like cmake-get[1] can install cget recipes directly in cmake without needing python installed.
Too many C++ tools couple package management and build
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.
There is cget which install cmake packages out of the box, so many libraries don't need to be updated to support it:
The way I tend to write code, is to just start with my main function and write whatever procedural code I need to solve my problem. If I start seeing patterns, in my data or algorithms, that's when I start pulling things out.
That is the same technique that Stephanov describes in 'From Mathematics to Generic Programming'.
C++ has already moved past OOP when it was standardized in the 90s by having a standard library built around regular types and generic programming. Here is Sean Parent's talk 'Inheritance Is The Base Class of Evil', which discusses some the same issues with OOP and the solution in C++:
https://channel9.msdn.com/Events/GoingNative/2013/Inheritanc...
First, there is commonmark that is trying to standardize markdown. There is also recommonmark which will parse commonmark for sphinx:
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.
I don't think ExternalProject manages the packages. For example, cget won't install the package again if its already installed.
I actually used python to make distribution easier. Otherwise, I would need to write Debian/RPM packages for linux, update homebrew for the mac, and windows installer for windows. So with python I just create one pypi package. It helps save time, since this is entirely a volunteer effort. Perhaps in the future, this could be written to run natively.
Essentially, the more abstract and generic things are (like Python)
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).