Re:Safety: A comparaison between Rust, C++ and Go
by dataflow on Saturday July 30, 2022 @07:23AM
(#32285953)
You can add [[clang::lifetimebound]] on the suffix parameter and you get
[ Parent
| on HN ]
Re:Safety: A comparaison between Rust, C++ and Go
by pfultz2 on Saturday July 30, 2022 @01:41PM
(#32288699)
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: UB
Re:Safety: A comparaison between Rust, C++ and Go
by dataflow on Saturday July 30, 2022 @02:06PM
(#32288912)
As awesome as that is, cppcheck doesn't seem ready for real-world use. Literally the first invocation I ran resulted in this error:
error: Syntax Error: AST broken, binary operator '!=' doesn't have two operands. [internalAstError]
explicit operator bool() const { return this->get() != pointer(); }
This is for a simple wrapper class that looks like this: template<class T>
class Foo : private Bar<T> {
public:
typedef value_type *pointer;
pointer get() const { return ...; }
explicit operator bool() const { return this->get() != pointer(); }
};
Another example: void foo(uintptr_t const (&input)[2]) {
if constexpr (sizeof(uintptr_t) == sizeof(int) && sizeof(long long) == 2 * sizeof(int)) {
long long value;
memcpy(&reinterpret_cast<uintptr_t *>(&value)[0], &input[0], sizeof(input[0]));
memcpy(&reinterpret_cast<uintptr_t *>(&value)[1], &input[1], sizeof(input[1]));
}
}
error: The address of local variable 'value' is accessed at non-zero index. [objectIndex]
memcpy(&reinterpret_cast<uintptr_t *>(&value)[1], &input[1], sizeof(input[1]));
^