I have a function which internally uses some helper functions to keep its body organized and clean. They're very simple (but not always short) (they're more than just 2), and could be easily inlined inside the function's body, but I don't want to do so myself because, as I said, I want to keep that function's body organized.
All those functions need to be passed some arguments by reference and modify them, and I can write them in two ways (just a silly example):
With normal functions:
void helperf1(int &count, int &count2) {
count += 1;
count2 += 2;
}
int helperf2 (int &count, int &count2) {
return (count++) * (count2--);
}
//actual, important function
void myfunc(...) {
int count = count2 = 0;
while (...) {
helperf1(count, count2);
printf("%d\n", helperf2(count, count2));
}
}
Or with lambda functions that capture those arguments I explicitly pass in the example above:
void myfunc(...) {
int count = count2 = 0;
auto helperf1 = [&count, &count2] () -> void {
count += 1;
count2 += 2;
};
auto helperf2 = [&count, &count2] () -> int {
return (count++) * (count2--);
};
while (...) {
helperf1();
printf("%d\n", helperf2());
}
}
However, I am not sure on what method I should use. With the first, one, there is the "overhead" of passing the arguments (I think), while with the second those arguments could be (are them?) already included in there so that that "overhead" is removed. But they're still lambda functions which should (I think, again) not be as fast as normal functions.
So what should I do? Use the first method? Use the second one? Or sacrifice readability and just inline them in the main function's body?
Your first and foremost concern should be readability (and maintainability)!
Which of regular or lambda functions is more readable strongly depends on the given problem (and a bit on the taste of the reader/maintainer).
Don't be concerned about performance until you find that performance actually is an issue! If performance is an issue, start by benchmarking, not by guessing which implementation you think is faster (in many situations compilers are pretty good at optimizing).
Performance wise, there is no real issue here. Nothing to decide, choose whatever.
But, Lambda expressions won't do you any good for the purpose you want them.
They won't make the code any cleaner.
As a matter of fact I believe they will make the code a bit harder to read compared to a nice calculator object having these helper functions as member functions properly named with clean semantics and interface.
Using Lambda is more readable but they are actually there for more serious reasons , Lambda expressions are also known as "anonymous functions", and are very useful in certain programming paradigms, particularly functional programming, which lambda calculus ( http://en.wikipedia.org/wiki/Lambda_calculus )
Here you can find the goals of using lambdas :
https://dzone.com/articles/why-we-need-lambda-expressions
If you won't need the two helper functions somewhere else in your code, then use your lambda method , but if you will call one of them again somewhere in your project avoid writing them each time as lambdas , you can make a header file called "helpers.(h/hpp)" & a source file called "helper.(c/cpp)" then append all the helper functions there then you gain the readability of both the helper file and the caller file
You can avoid this unskilled habit and challange yourself by writing complex code that you have you read it more than once each time you want to edit it , that increases your programming skills and if you are working in a team , it won't be a problem , use comments , that will let them show more respect to your programming skills (if your complex code is doing the expected behaviour and giving the expected output)
And don't be concerned about performance until you find yourself writing a performance critical algorithm , if not , the difference will be in few milliseconds and the user won't notice it , so you will be loosing you time in an optimization that compiler can do by itself most of the time if you ask him to optimize your code .
Related
This question already has answers here:
Modern C++ way to repeat code for set number of times
(3 answers)
Closed 2 years ago.
I want to execute a single operation multiple times, without defining a counter. For example, like this:
do(10)
{
//do something
}
I think this would be useful in several different scenarios. For example:
Deleting several consecutive items from std::list by a beginning index.
Emitting some signal several times, either over time or at some specific time.
Adding the same data to the list for custom initialization
Many scenes are not limited to those listed above.
Other languages have syntax similar to this that allows repeatedly executing the same command, without having to explicitly define a counter variable.In my opinion,defining a counter is completely inconsistent with human thinking.
Simulate how we think:
In reality, we always do sth. a few times directly.
But now the syntax looks like this:
Uh...I am going to do sth. three times.
Okay,ready,I started.
Soul torture: Why doesn't C++ provide a concise syntax? Although I am a fan of C++, I can’t help but wonder why some people don’t like C++ because C++ rarely considers how people think.I hope C++ can advance with the times and become the programming language of the future.
Different from Modern C++ way to repeat code for set number of times.I gave my plan, application scenarios, and even emotional appeals.
The evolution of C++ is by committee. In the simplest terms folk propose stuff and the committee accepts or rejects it.
Interestingly your suggestion
do (integral_expression)
{
}
would not be a breaking change. Note there's no while after the loop body or while adjacent to do. integral_expression is almost a production rule in C++ in case labels of switch blocks, although it could be run-time evaluable in this case. It could even lend itself to clean code in the sense that the equivalent
for (int i = 0; i < integral_expression; ++i)
{
}
introduces i into the loop body which can be inconvenient as it can shadow an existing i.
That said, thought is needed for the case where integral_expression is negative. Perhaps introduce unsigned_integral_expression not unlike what needs to be written as the size expression when declaring a variable length array in a reasonably common extension to standard C++?
If you want this feature in C++, then why not propose it?
Here is an example of C++ code that will do something a given number of times. Could also be done in C, but the functor would have to be a function pointer.
There may be a use case for this, but I'd think that for C++ programs the standard loop syntax would be preferable.
#include <iostream>
#include <functional>
static void Do(int count, std::function<void(int)> fn)
{
while(count)
{
if (count > 0) --count;
else if (count < 0) ++count;
fn(count);
}
}
int main()
{
Do(10, [](int count) { std::cout << "Loop is at " << count << "\n"; });
}
lambdas make a clean pure library implementation possible if needed:
template<typename F>
constexpr void repeat(std::size_t const n,F const& f){
for (std::size_t i=0;i<n;++i)
f();
};
int x{};
repeat(5,[&]{
std::cout << ++x << std::endl;
});
such a proposal is likely to get discarded by the committee, unless greater reasons support it.
I had pleasure of working with function pointers lately. I got to know how they work. Classical example of function pointers is :
int add() {
return (100+10);
}
int sub() {
return (100-10);
}
void print(int x, int y, int (*func)()) {
printf("value is : %d", (x+y+(*func)()));
}
int main() {
int x=100, y=200;
print(x,y,add);
print(x,y,sub);
}
Somebody asked me the other day that how is it better than calling(inside main):
print(add(x,y));
print(sub(x,y));
and I struggled to explain that. Is it only about the stack or there is something else lying underneath?
I don't really understand why the code you show would be a classical example of function pointers. Functions pointers' utility is much more obvious from code like this:
void transform(int *dst, const int *src, size_t len, int (*f)(int))
{
for (size_t i = 0; i < len; ++i)
dst[i] = f(src[i]);
}
Basically, if you accept a pointer to function as a parameter, it allows you to apply a client-provided operation on data of your choice.
The classic use case (which generalizes) is qsort (https://linux.die.net/man/3/qsort). The sort algorithm is general purpose but the implementation does not know how to compare items because they can be of any type. So you pass in a function that it can call in order to compare two elements.
Function pointers are pretty much useless overhead if you hard coded call the one or the other, like your example. Their power comes from being able to dynamically pick and use them, or pass them to other functions:
You can put function pointers in an array, and loop over them; or you can call a selected one based on a user-input or input file content, or other circumstances. In both cases, they will allow to write code that has a single dynamic call, instead of potential long switch or if statement chains.
The second - and even more useful - concept is to pass them to some other function (also sometimes called 'callbacks'); a classic example is to call qsort with your data table and a custom comparison function in form of a function pointer. qsort will then use your comparison function inside the standardized sort algorithm; there is no other way to implement this.
"pointer to function" is an object. So it can be copied,stored,assigned like any other object.
Where as references to functions (normal functions) are not objects.
I think the classic example is.... User interfaces events handling by using callback functions, which has become an obvious pattern for any UI software.
ref auto opIndex(size_t i){
return t[i];
}
Here t is a tuple and i needs to be read at compile time. How would I express this in D?
There isn't any clean way to do this with opIndex currently, for two reasons. First is simple - it isn't implemented. That would be relatively easy to fix on its own but there is a second reason - it adds serious context sensitivity to language grammar.
Consider this struct definition:
struct S
{
// imagine this works, syntax is not important
static int opIndex (size_t i) { return 42; }
}
Now what does the code S[10] mean? Is it a static array type of ten S elements? Or static opIndex call which returns 42? It is impossible to tell without knowing quite a lot of context and in certain cases impossible to tell at all (like typeof(S[10])).
Somewhat relevant (unapproved!) idea: http://wiki.dlang.org/DIP63
enum { WITH_ZERO };
auto copy_num = [](int n, char target[NUM_LEN]) -> int {
char temp;
for (int j = NUM_LEN - 1; j >= 0; j--) {
if ((temp = n % 10 + '0') == '0') {
return WITH_ZERO;
} else {
target[j] = temp;
n /= 10;
}
}
return !WITH_ZERO;
};
if (copy_num(i, num_copy) == WITH_ZERO) {
continue;
}
if (i * 3 > MAX_NUM) {
continue;
}
copy_num(i * 2, num_double);
copy_num(i * 3, num_triple);
//edit: changed 'goto' to 'continue'
The above is part of my code, which should show in what cases I would prefer to use nested lambdas. I can achieve similar to this with macros, but they do make my codes dirtier, while the lambdas used this way look more clean, without the '\'s. The 'copy_num' function here is only used locally and not anywhere else, so this has more readability than when defining 'copy_num' as a normal function outside. Lambdas can also conveniently catch outer variables if needed, in which case I can reduce repetitive function parameters, again making clearer code.
By using lambdas this way several times, I wondered whether it is a good or bad idea to use lambdas as an entire replacement to functions. Lambdas can work perfectly well as a more flexible form of functions possible to be nested or anonymous. In cases where what the lambdas do are of no difference than what a normal function of a same form would do, the compiler will be smart enough to compile them as if being plain functions.
Or perhaps future c/c++ will allow nested functions in general?
I do not think there is anything wrong with this approach. It is certainly safer than C'ish #define's, the savings in \s being the least advantage I can think of.
Until lambda support has matured, you may see compilers struggle to generate 'optimal' code though.
Lambdas can also conveniently catch outer variables if needed, in which case I can reduce repetitive function parameters, again making clearer code.
Yes, and once needed elsewhere, the lambda + capture can easily be migrated to a class that holds state and defines some operations on it.
Or perhaps future c/c++ will allow nested functions in general?
This is fully-fleshed support for nested functions. Remember, a lambda that does not capture can decay to a function pointer.
I am currently working on a tool, that will compare two files and report its differences. I want to implement a feature that will compare two methods, and report if they are identical (while ignoring variable name changes ). What i have thought of doing, is to Normalize all the variable names to (x0,x1 ..) or something similiar. Then sort the methods ( Alphabetically? ) so that the order is the same. Grap their checksums and then compare the two.
My question:
How do i normalize variable names in a C / C++ file?
or
Do you have any other ideas as to how i could implement the feature?
Regards
You can map 'tokens' (variable names) to an 'interned form', as described above, if you can come up with a repeatable & stable ordering.
This doesn't attempt to understand how the tokens resolve, merely that they are present in the same pattern in two source-files. "Tokens" would be everything other than C/C++ reserved words, no serious parsing/ lexing necessary.
Once you have done that you can convert comments & whitespace to a canonical form.
This wouldn't mostly be of utility to me, but I believe it would achieve a 99.9% or better stab at the problem -- it's conceivable that it could be fooled, but practically not very likely.
Of course, if we have macros those have to handled too.. maybe you can run the C pre-processor on them to fulfill that, if that's a requirement?
Hope this helps.
Surely this is not about normalizing the names, but about figuring out if the two methods do the same thing to the same things within a class. Which means parsing the source code and building some sort of data structure [probably a "tree"] from that. Once you have the tree, the names as such will become meaningless. You may need to track for example what OFFSET into a class member variables are referring to, and which virtual functions within a class.
I don't believe this is at all trivial (unless you restrict the code to a small subset of C++ code), since there are so many different ways to make something do the same thing, and just subtle difference will throw off anything by the most sophisticated of tools. E.g.
class A
{
private:
int arr[10];
...
public:
int sum()
{
int r = 0;
for(i = 0; i < 10; i++)
r += arr[i];
return r;
}
}
class B
{
private:
int arr[10];
...
public:
int sum()
{
int r = 0;
int *p = arr;
for(i = 0; i < 10; i++)
r += *p++;
return r;
}
....
}
These two functions do the same thing.
What about using the temporary tree representation gcc generates during compilation, gcc has a command-line-switch to preserve temporary files:
gcc -save-temps <file>
This code is somewhat simplified and names are unified. The problem is to identify the differences in the original file.
Do not use Optimization!