What is a minimal example of why it is not possible to predict call pattern of functions? - compilation

A stack makes it possible to execute subroutines in any order, nested subroutines and recursive subroutines, and to jump to and back from the subroutines, and to call functions with arbitrary arguments. This is important because it is impossible to predict the call pattern of the functions (and therefore impossible to print out all uses of subroutines explicitly in the instruction sequence), this answer says.
What is a minimal example of a program that shows that this (call pattern of functions) cannot be known beforehand?

Peter Cordes comment mentions functions pointers and I agree that is a good example. I also disagree with that the answer in the linked question, recursion, is true (the call pattern is predictable, just not how much of the call pattern will be executed), so it was good that I asked and got a clarified answer that I can agree with.
I came up with a minimal example as a program (as question states, "what is a minimal example of a program") that shows clearly how function pointers make it impossible to predict call pattern.
It has 10 functions, all called using a function pointer.
It then requests the function pointer value from the user (so that it could not be known at compile time), and executes the function. It then loops, and does it again, and again, and again.
The possible combinations of call pattern for the functions is 10^n I think, where n is number of times the loop is run. It becomes a billion if you run the loop 9 times.
That is a pretty good minimal example, that shows it with probability theory.
#include <stdio.h>
void a() {}
void b() {}
void c() {}
void d() {}
void e() {}
void f() {}
void g() {}
void h() {}
void i() {}
void j() {}
int main(void)
{
void (*foo)(); //to store memory address
while (true) {
printf("Now, read/input the memory address: ");
scanf ("%p", &foo);
foo();
}
return 0;
}

Related

Understand function parameters(pass by value instead of by const reference) in boost::beast client example websocket_client_async_ssl.cpp

Reference:
boost_1_78_0/doc/html/boost_asio/reference/ip__basic_resolver/async_resolve/overload1.html
template<
typename ResolveHandler = DEFAULT>
DEDUCED async_resolve(
const query & q,
ResolveHandler && handler = DEFAULT);
The handler to be called when the resolve operation completes. Copies
will be made of the handler as required. The function signature of the
handler must be:
void handler(
const boost::system::error_code& error, // Result of operation.
resolver::results_type results // Resolved endpoints as a range.
);
boost_1_78_0/libs/beast/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp
void run(char const *host, char const *port, char const *text) {
...
resolver_.async_resolve(
host, port,
beast::bind_front_handler(&session::on_resolve, shared_from_this()));
}
void on_resolve(beast::error_code ec, tcp::resolver::results_type results) {
if (ec)
return fail(ec, "resolve");
// Set a timeout on the operation
beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));
// Make the connection on the IP address we get from a lookup
beast::get_lowest_layer(ws_).async_connect(
results,
beast::bind_front_handler(&session::on_connect, shared_from_this()));
}
Question 1> Why does the on_resolve use the following function signature?
on_resolve(beast::error_code ec, tcp::resolver::results_type results)
As shown above, the first parameter(i.e. ec) is taken as pass-by value. This happens almost in all other functions which take a beast::error_code as an input parameter within sample code.
Instead of
on_resolve(const beast::error_code& ec, tcp::resolver::results_type results)
Question 2> Why doesn't the documentation suggest using the following instead?
on_resolve(const beast::error_code& ec, const tcp::resolver::results_type& results)
Thank you
It's a cultural difference between Asio and Beast if you will.
UPDATE
There's some contention about my initial response.
It turns out that at least Boost System's error_code recently got endowed with shiny new (non-standard) features, that makes it bigger. Perhaps big enough to make it more efficient to pass by reference.
In the words of Vinnie Falco: This needs to be studied again.
Rationale
In Asio, the standard "doctrine" is to take error_code by const&. In Beast, the standard practice is actually to pass by value, which is, IMO, how error_code is intended.
In essence, error_code is just a tuple of (int, error_category const*) which is trivially copied and therefore optimized. Passing by value allows compilers much more room for optimization, especially when inlining. A key factor is that value-arguments never create aliasing opportunities.
(I can try to find a reference as I think some Beast devs are on record explaining this rationale.)
Why is it OK?
Any function that takes T by value is delegation-compatible with the requirement that it takes T by const reference, as long as T is copyable.
Other thoughts
There may have been historical reasons why Asio preferred, or even mandated error_code const& in the past, but as far as I am aware, any of these reasons are obsolete.

Idiomatic way of providing constructors that move their arguments

Lets say I have the following class:
#include <vector>
class Foo
{
public:
Foo(const std::vector<int> & a, const std::vector<int> & b)
: a{ a }, b{ b } {}
private:
std::vector<int> a, b;
};
But now I want to account for the situations in which the caller of the constructor might pass temporaries to it and I want to properly move those temporaries to a and b.
Now do I really have to add 3 more constructors, 1 of which has a as a rvalue reference, 1 of which has b as a rvalue reference and 1 that only has rvalue reference arguments?
Of course this question generalizes to any number of arguments which are worthwhile to move and the number of required constructors would be arguments^2 2^arguments.
This question also generalizes to all functions.
What is the idiomatic way of doing this? Or am I completely missing something important here?
The usual approach is to pass by value, then move-construct the members from the parameters:
Foo(std::vector<int> a, std::vector<int> b)
: a{ std::move(a) },
b{ std::move(b) }
{}
If a copy is needed, it will be created by the caller and then moved-from to construct the member. If the caller passes a temporary (or other rvalue), no copy is made, only a single move.
For arguments that don't have an efficient move constructor, then accepting a reference to const is slightly more efficient, and I'd retain that.
None of this applies if the function doesn't need a copy of the passed value - continue to use a const ref if you don't modify the value and don't need it to live beyond the end of the function execution. Personally, I use pass-by-value-and-move liberally in my constructors, but rarely in my other functions.
Really, you should take by value if move construction is very cheap.
This results in exactly 1 extra move over the ideal case in every case.
But if you really must avoid that, you can do this:
template<class T>
struct sink_of {
void const* ptr = 0;
T(*fn)(void const*) = 0;
sink_of(T&& t):
ptr( std::addressof(t) ),
fn([](void const*ptr)->T{
return std::move(*(T*)(ptr));
})
{}
sink_of(T const& t):
ptr( std::addressof(t) ),
fn([](void const*ptr)->T{
return *(T*)(ptr);
})
{}
operator T() const&& {
return fn(ptr);
}
};
which uses RVO/elision to avoid that extra move at the cost of a bunch of pointer-based overhead and type erasure.
Here is some test code that demonstrates that
test( noisy nin ):n(std::move(nin)) {}
test( sink_of<noisy> nin ):n(std::move(nin)) {}
differ by exactly 1 move-construct of a noisy.
The "perfect" version
test( noisy const& nin ):n(nin) {}
test( noisy && nin ):n(std::move(nin)) {}
or
template<class Noisy, std::enable_if_t<std::is_same<noisy, std::decay_t<Noisy>>{}, int> = 0 >
test( Noisy && nin ):n(std::forward<Noisy>(nin)) {}
has the same number of copy/moves as the sink_of version.
(noisy is a type that prints information about what moves/copies it engages in, so you can see what gets optimized away by elision)
This is only worth it when the extra move is important to eliminate. For a vector it is not.
Also, if you have a "true temporary" you are passing, the by-value one is as good as the sink_of or "perfect" ones.

Which is better: explicit or typeless get()?

Suppose the following two versions of the same class A:
Version 1
class A
{
public:
enum class Retrievable { Integer, String };
A(): m_integer(123), m_string("string") {}
~A() {}
void* get(const Retrievable r)
{
switch (r)
{
case Retrievable::Integer:
return static_cast<void*>(&m_integer);
case Retrievable::String:
return static_cast<void*>(&m_string);
default:
throw;
}
}
private:
int m_integer;
std::string m_string;
};
Version 2
class A
{
public:
A(): m_integer(123), m_string("string") {}
~A() {}
int getInteger() { return m_integer; }
std::string getString() { return m_string; }
private:
int m_integer;
std::string m_string;
};
In terms of clarity, efficiency, and extensibility, which of these two paradigms -- a single typeless get() function or separate explicit get() functions -- is better?
Option 1 casts things to void* and does run time dispatching, such is slower and less safe and harder to use.
Barring interacting with a scripting engine, I cannot imagine a reason to use option 1. And even then there are many better ways to handle it. An interviewee who proposed option 1 as even an alternative choice to option 2 would be a strong do not hire, and it would make me reconsider the funnel that got the interviewee this far.
In short, option 2 is better.
Version A will not compile anyway, because regardless of C you will try to return type which is not C (pointer where C is string etc.)
Version B is maybe better, but also quit crooked. unless you are building some polymorphic type like JSON node or something, the function should describe behaviour, not return type.
again, unless you are writing some JSON class, I don't see much sense of making a function which describe return type rather than behaviour. a Person doesn't have getHand or getLeg functions, he has functions like wave, walk etc.
performace? I doubt that a getter will screw the performance of your application.

why does std::for_each iterator need a copy constructable iterator

I noticed that std::for_each requires it's iterators to meet the requirement InputIterator, which in turn requires Iterator and then Copy{Contructable,Assignable}.
That's not the only thing, std::for_each actually uses the copy constructor (cc) (not assignment as far as my configuration goes). That is, deleting the cc from the iterator will result in:
error: use of deleted function ‘some_iterator::some_iterator(const some_iterator&)’
Why does std::for_each need a cc? I found this particularly inconvenient, since I created an iterator which recursively iterates through files in a folder, keeping track of the files and folders on a queue. This means that the iterator has a queue data member, which would also have to be copied if the cc is used: that is unnecessarily inefficient.
The strange thing is that the cc is not called in this simple example:
#include <iostream>
#include <iterator>
#include <algorithm>
class infinite_5_iterator
:
public std::iterator<std::input_iterator_tag, int>
{
public:
infinite_5_iterator() = default;
infinite_5_iterator(infinite_5_iterator const &) {std::cout << "copy constr "; }
infinite_5_iterator &operator=(infinite_5_iterator const &) = delete;
int operator*() { return 5; }
infinite_5_iterator &operator++() { return *this; }
bool operator==(infinite_5_iterator const &) const { return false; }
bool operator!=(infinite_5_iterator const &) const { return true; }
};
int main() {
std::for_each(infinite_5_iterator(), infinite_5_iterator(),
[](int v) {
std::cout << v << ' ';
}
);
}
source: http://ideone.com/YVHph8
It however is needed compile time. Why does std::for_each need to copy construct the iterator, and when is this done? Isn't this extremely inefficient?
NOTE: I'm talking about the cc of the iterator, not of it's elements, as is done here: unexpected copies with foreach over a map
EDIT: Note that the standard does not state the copy-constructor is called at all, it just expresses the amount of times f is called. May I then assume that the cc is not called at all? Why is the use of operator++ and operator* and cc not specified, but the use of f is?
You have simply fallen victim to a specification that has evolved in bits and pieces over decades. The concept of InputIterator was invented a long time before the notion of move-only types, or movable types was conceived.
In hindsight I would love to declare that InputIterator need not be copyable. This would mesh perfectly with its single-pass behavior. But I also fear that such a change would have overwhelming backwards compatibility problems.
In addition to the flawed iterator concepts as specified in the standard, about a decade ago, in an attempt to be helpful, the gcc std::lib (libstdc++) started imposing "concepts" on things like InputIterator in the std-algorithms. I.e. because the standard says:
Requires: InputIterator shall satisfy the requirements of an input iterator (24.2.3).
then "concept checks" were inserted into the std-algorithms that require InputIterator to meet all of the requirements of input iterator whether or not the algorithm actually used all of those requirements. And in this case, it is the concept check, not the actual algorithm, that is requiring your iterator to be CopyConstructible.
<sigh>
If you write your own for_each algorithm, it is trivial to do so without requiring your iterators to be CopyConstructible or CopyAssignable (if supplied with rvalue iterator arguments):
template <class InputIterator, class Function>
inline
Function
for_each(InputIterator first, InputIterator last, Function f)
{
for (; first != last; ++first)
f(*first);
return f;
}
And for your use case I recommend either doing that, or simply writing your own loop.

Is it possible to write a generic function that distiguishes between an rvalue and an lvalue?

I am trying to learn rvalue references, as an exercise I tried to do answer the following.
Is it possible to write a function that can tell (at least at runtime, better if at compile time) if the passed value is a value (non reference), a rvalue or an lvalue? for a generic type? I want to extract as much information about the type as possible.
An alternative statement of the problem could be:
Can I have a typeid-like function that can tell as much as possible about the calling expression?, for example (and ideally) if the type is T, T&, T const&, or T&&.
Currently, for example, typeid drops some information about the type and one can do better (as in the example the const and non-const reference are distiguished). But how much better than typeid can one possibly do?
This is my best attempt so far. It can't distinguish between a rvalue and a "constant". First and second case in the example).
Maybe distiguishing case 1 and 2 is not possible in any circumstance? since both are ultimately rvalue? the the question is Even if both are rvalues can the two cases trigger different behavior?
In any case, it seems I overcomplicated the solution as I needed to resort to rvalue conditional casts, and ended up with this nasty code and not even 100% there.
#include<iostream>
#include<typeinfo>
template<class T>
void qualified_generic(T&& t){
std::clog << __PRETTY_FUNCTION__ << std::endl;
std::clog
<< typeid(t).name() // ok, it drops any qualification
<< (std::is_const<typename std::remove_reference<decltype(std::forward<T>(t))>::type>::value?" const":"") // seems to detect constness rigth
<< (std::is_lvalue_reference<decltype(std::forward<T>(t))>::value?"&":"")
<< (std::is_rvalue_reference<decltype(std::forward<T>(t))>::value?"&&":"") // cannot distiguish between passing a constant and an rvalue expression
<< std::endl
;
}
using namespace std;
int main(){
int a = 5;
int const b = 5;
qualified_generic(5); // prints "int&&", would plain "int" be more appropriate?
qualified_generic(a+1); // prints "int&&" ok
qualified_generic(a); // print "int&", ok
qualified_generic(b); // print "int const&", ok
}
Maybe the ultimate solution to distiguish between the cases will involve detecting a constexpr.
UPDATE: I found this talk by Scott Meyers where he claims that "The Standard sometimes requires typeid to give the 'wrong' answer". http://vimeo.com/97344493 about minute 44. I wonder if this is one of the cases.
UPDATE 2015: I revisited the problem using Boost TypeIndex and the result is still the same. For example using:
template<class T>
std::string qualified_generic(T&& t){
return boost::typeindex::type_id_with_cvr<decltype(t)>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T&&>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T&>().pretty_name();
}
Still it is not possible to distinguish the type of 5 and a+1 in the above example.

Resources