Out of curiosity, I tested the size of a lamba expression. My first thought was, that they'd be 4 bytes big, like a function pointer. Strangely, the output of my first test was 1:
auto my_lambda = [&]() -> void {};
std::cout << sizeof(my_lambda) << std::endl;
Then I tested with some calculations inside the lambda, the output still being 1:
auto my_lambda2 = [&]() -> void {int i=5, j=23; std::cout << i*j << std::endl;};
std::cout << sizeof(my_lambda2) << std::endl;
My next idea was kinda random, but the output finally changed, displaying the awaited 4:
auto my_lambda3 = [&]() -> void {std::cout << sizeof(my_lambda2) << std::endl;};
std::cout << sizeof(my_lambda3) << std::endl;
At least in Visual Studio 2010. Ideone still display 1 as the output.
I know of the standard rule, that a lambda expression cannot appear in an unevaluated context, but afaik that only counts for direct lambda use like
sizeof([&]() -> void {std::cout << "Forbidden." << std::endl;})
on which VS2010 prompts me with a compiler error.
Anyone got an idea what's going on?
Thanks to #Hans Passant's comment under the question, the solution was found. My original approach was wrong in the fact that I thought every object would be captured by the lambda, but that isn't the case, only those in the enclosing scope are, and only if they are used.
And for everyone of those captured objects, 4 bytes are used (size of the reference).
Visual Studio probably doesn't implement lambda objects as functions. You're probably getting an object back. Who knows what it looks like. If you're truly interested you could always look at your variables with a debugger and see what they look like...if it'll let you.
Related
This is a multi part question based on a project I'm currently undertaking. I will try to make it as brief as possible while still fully explaining the question, so sorry if this is a bit long.
When it comes to std::vectors in C++, how exactly do they work with variables? For example, if I have the following code:
int myInt = 4;
std::vector<int> myIntVector;
myIntVector.push_back(myInt);
what happens? Does that area of memory inside myIntVector now have the same value of data stored inside myInt at the time of adding, but still completely separate them? Does the area of memory where myInt is stored get physically moved into a designated area inside of the memory of myIntVector?
Assuming I was correct on the last statement, why would std::cout << myInt still correctly print 4, assuming it was not changed, while std::cout << myIntVector[0] also prints out 4?
Now, for what prompted the question: the #define directive. I was experimenting with this for my project, and noticed something interesting. I used #define GET_NAME(variable) (#variable), which returns the name of the inputted variable as a character array. If I were to have the following code:
#define GET_NAME(variable) (#variable)
int myInt = 4;
std::vector<int> myIntVector;
myIntVector.push_back(myInt);
std::cout << GET_NAME(myInt) << "\n";
std::cout << GET_NAME(myIntVector[0]);
I would receive the following output:
myInt
myIntVector[0]
Why? Assuming the first statement from question 1 is correct, this is the expected output, but then we circle back to question 2. Assuming the second statement from question 2 is correct, this is the unintended output, as myInt or myIntVector[0] should be returned twice.
Thanks in advance!
When it comes to std::vectors in C++, how exactly do they work with variables?
All STL containers just copy values by default. So when you pass an int variable, it gets copied and the copy exist completely independently from the original value
why would std::cout << myInt still correctly print 4, assuming it was not changed, while std::cout << myIntVector[0] also prints out 4?
These are two different values, both equal to 4
If I were to have the following code, I would receive the following output. Why?
The macros just manipulate the text, and don't do anything fancy in your code. This statement:
std::cout << GET_NAME(myInt) << "\n";
Just turns into this under the macro:
std::cout << "myInt" << "\n";
I'm reading Inside The C++ Object Model and find confused about inline function expansion.
In general, each local variable within the inline function must be introduced into the enclosing block of the call
as a uniquely named variable. If the inline function is expanded multiple times within one expression, each
expansion is likely to require its own set of the local variables. If the inline function is expanded multiple
times in discrete statements, however, a single set of the local variables can probably be reused across the
multiple expansions.
Here, what does it mean to expand inline function multiple times in discrete statements and how could that happen? Can anyone raise a concrete example to apply this?
I had some trouble to handle the term discrete statement (especially because it has been emphasized multiple times). I tried to find something like a clear definition (by google) but I couldn't. Thus, I decided to read this literally as one statement (with discrete in the sense of separate).
Denoting a function inline is just a hint to the compiler that the programmer would like to have the function body inserted directly at every "call point" (instead of simply calling the function). Actually, the compiler decides whether the function is really inlined. (It might be even inlined at one point of call but become a function call at another point.) If a macro is used instead of the inline function, the inline requirement would be granted (as macro expansion is actually nothing else than text replacement). Of course, macros have a lot of limitations which inline functions have not. One of them is that inline functions may have local variables.
I made a synthetic example. It's not code "ready for production" but it hopefully helps to illustrate the topic:
#include <iostream>
using namespace std;
inline int absValue(int a)
{
int mB = -a;
return a < 0 ? mB : a;
}
int main()
{
int value;
// use input to prevent compile-time computation
cout << "input: " << flush;
cin >> value;
// multiple usages of absValue()
cout << "value: " << value << endl
<< "absValue(value): "
<< absValue(value)
<< endl
<< "absValue(-value): "
<< absValue(-value)
<< endl;
// done
return 0;
}
The second output statement calls function absValue() multiple times where the call should be inlined. I imagine it like:
// multiple usages of absValue()
cout << "value: " << value << endl
<< "absValue(value): "
<< {
int mB = -(value);
return (value) < 0 ? mB : (value);
}
<< endl
<< "absValue(-value): "
<< {
int mB = -(-value);
return (-value) < 0 ? mB : (-value);
}
<< endl;
There are two occurrences of mB in this statement. On one hand, these are two separate local variables. On the other hand, they may share the same storage on stack as they are used consecutively. (They might not share the same storage if the compiler optimization introduces some kind of code re-ordering which results in interleaving of the first and second expansion of absValue().)
This whole explanation is rather theoretically. Practically, the compiler will hopefully put mB into a register or even optimize most of the code away.
I fiddled a little bit with godbolt to illustrate it further. Finally, I must admit that it proofs essentially my last paragraph above.
Often I just want to quickly check the contents of a series of variables (let's call them a,b,c,d and e, and suppose they're a mixture of floats, integers and strings). I'm fed up typing
cout << a << " " << b << " " << " " << c << " " << " " << d << " " << e << endl;
Is there a more convenient (less key-strokes) way to quickly dump a few variables to stdout in C++? Or do C++ people just always define their own simple print function or something? Obviously something like
printf("%d %f %s %d %s\n",a,b,c,d,e);
is not the alternative I'm looking for, but rather something like
print a,b,c,d,e
Even
print*, a,b,c,d,e
or
write(*,*) a,b,c,d,e
isn't too inconvenient to type.
Of course, googling 'quickly print to screen in C++' keeps just sending me back to std::cout.
Is it that, what you want?
print(a, b, c);
That would be this.
template <typename T>
void print(T t)
{
std::cout << t << " ";
}
template<typename T, typename... Args>
void print(T t, Args... args)
{
std::cout << t << " ";
print(args...) ;
}
It's easy to create a "print" class which have an overloaded template operator,, then you could do something like
print(),a,b,c,d;
The expression print() would create a temporary instance of the print class, and then use that temporary instance for the printing with the comma operator. The temporary instance would be destroyed at the end of the expression (after last comma overload is called).
The implementation could look something like this:
struct print
{
template<typename T>
print& operator,(const T& v)
{
std::cout << v;
return *this;
}
};
Note: This is just off my head, without any testing.
Is there a more convenient (less key-strokes) way to quickly dump a
few variables to stdout in C++?
I would have to say No, not in the language. But I do not consider std::cout a challenging amount to type.
You can tryout the template methods provided by other answer's.
But you should try GDB (or some debugger available on your system). GDB can 'dump' automatic variables with no _effort_ at all, as automatic var's for the current stack frame are always kept up-to-date in the "Locals" window.
Or do C++ people just always define their own simple print function or something?
No, or maybe something.
I use std::cout and std::cerr (as defined) for lots of debugging, but not in the 'how can I save the most typing' frame of mind.
My view is that creating a 'convenience' (i.e. not required) function is appropriate for doing something you wish to repeat. My rule of thumb is 3 times ... if I do a particular something 3 (or more) times (like generate a std::cout statement with the same or similar variables in it) then I might write a function (rather than copy the line) for that repeated effort.
Typically, I use one of two (what I call) disposable debug methods ... and most of my objects also have both show() and dump(), and there can be multiple show/dump functions or methods, each with different signatures, and default values.
if(dbg1) show(a,b,c,d,e);
if(dbg1b) show(b);
// etc
and
if(dbg2) dump(a,b,c,d,e);
Show typically uses and does what what std::cout provides, and little else.
Dump does what show does, but also might provide an alternate view of the data, either hex or binary translations of the values, or perhaps tables. What ever helps.
Disposable does not mean I will dispose of them, but rather I might, and I often get tired of output that does not change, so I set dbgX to false when this code seems to be working, at least until I decide to dispose of the debug invocation.
But then, you do have to implement each of the functions and methods, and yes, you are going to have to learn to type.
If these variables are automatic, you should know that the debugger GDB automatically displays them in a window called "Locals", and keeps them up-to-date during single step.
In GDB, object instance contents can often be displayed with "p *obj", and there are ways to add a particular obj name to the local display window.
It does not take a lot to run GDB. If you object to creating the 80 char std::cout code above, it takes far less typing to launch GDB, set break in main, and run the simple task under gdb control, (then single step to observe these variables at any step in your code) not just where you happened to insert a show() or dump() command.
And if you have GDB, you can also command to print using "p show()" (when the show() function is in scope) to see what the in-scope variables look like to std::cout (if you don't believe the "Locals" window).
GDB allows you to "p this->show()" when stepping through a method of the instance, or "p myObj->show()" when the myObj is accessible.
ALso, "p *this" and "p *myObj" will provide a default, typically useful, display of the current contents your object.
Anyway. Yes you can always work hard to shorten your typing effort.
I'm at the end of my rope here: I have a single-threaded C++ program. Here is some empirical data and background information, I tried to highlight the most important keywords;
The entire section I'm talking about does not have any syscalls, other than the memory (de-)allocation calls the standard C++ library may perform (std::sets are involved). It's a purely logical algorithm.
The behaviour of this should be deterministic, depending on the input, which I do not vary.
If the bug manifests itself, the program simply falls into what looks like an endless loop where it seems to start allocating memory beyond any bound.
The bug does not manifest itself predictably, I can run the program from the command line and sometimes (perhaps 30%-50%) the bug manifests itself, otherwise, everything runs smoothly and correctly as far as I can tell.
Once I run the program not directly from the prompt, but in gdb or valgrind, the bug is gone, the program never dies.
Now comes the best part: I traced the problem to a (templated) non-virtual member function call. Just before the call, I print a message to std::cout, which I can see in the terminal. The first line inside the function also has a debug message, which is never shown.
I don't see any reasonable explanation any more. Maybe you can come up with an idea how to proceed.
Edit: The significant lines of code, I changed the line numbers so we can refer to them and omitted irrelevant parts, so not everything seems to make the best sense.
a.cpp
10 std::set<Array const*>* symbols;
11 std::set<Array const*> allSymbols;
12 symbols = &allSymbols;
// ... allSymbols are populated with std::inserter
15 std::cout << "eval; cd = " << &cd << ", cg = " << &cd.cg << std::endl;
16 senderConstraints = cd.cg.eval(*symbols);
b.cpp
31 template <typename ArrayContainer>
32 ConstraintList eval(ArrayContainer const request) {
33 std::cout << "inside eval ... going to update graph now" << std::endl;
The last line of output is:
eval; cd = 0x2e6ebb0, cg = 0x2e6ebc0
Then it's trapped in the endless loop.
I bet, the second line is printed, when you change
ConstraintList eval(ArrayContainer const request)
to
ConstraintList eval(ArrayContainer const & request)
If so, either the state of allSymbols is corrupted between line 12 and line 15, or your code really looks more like this:
std::set<Array const*>* symbols;
{
std::set<Array const*> allSymbols;
symbols = &allSymbols;
// ... allSymbols are populated with std::inserter
}
std::cout << "eval; cd = " << &cd << ", cg = " << &cd.cg << std::endl;
senderConstraints = cd.cg.eval(*symbols);
Which is UB, because symbols refers to an already destructed object.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Modifying a const through a non-const pointer
I'm studying C++, and very interesting about pointers. And I tried to change value of a constant value (my teacher called it backdoor, please clarify if I'm wrong) like this:
const int i = 0;
const int* pi = &i;
int hackingAddress = (int)pi;
int *hackingPointer = (int*)pi;
*hackingPointer = 1;
cout << "Address:\t" << &i << "\t" << hackingPointer << endl;
cout << "Value: \t" << i << "\t\t" << *hackingPointer << endl;
system("PAUSE");
return 0;
However, the result is very strange. Although the two addresses are the same, the values are different.
How is my code executed? And where is 0 and 1 value is stored exactly?
You've discovered a little thing that C++ developers call undefined behavior. You told the compiler that "i is a constant with the value 0". So when you ask the compiler for the value of i, it tells you that it is 0.
Mucking around with trying to change the value of a constant violates the assumptions made by the compiler (that constants are going to be, well, constant), and so, the compiler is going to generate invalid or inconsistent code.
There are a lot of situations in C++ where it is possible to do something without the compiler catching it as an error, but the result is undefined. And if you do that, then you get results like what you're seeing. The compiler does something weird and unexpected.
Oh, and if your teacher is trying to teach you anything from an example such as this, he's wrong, and you should be very scared.
The only guarantee you get from code like this is this:
the compiler can do literally anything it likes
When you write code, you have an implicit contract with the compiler:
"If I write well-defined C++ code, then you convert it into an executable with the same effects as described by the C++ standard".
When you do something like this, you violate the contract. And then the compiler isn't obliged to follow it either. If you give the compiler code that is not well-defined according to the C++ standard, then it can't, and isn't going to, create an executable which does as the C++ standard specifies.
It seems, that compiler has optimized (inlined int const value)
cout << "Value: \t" << i << "\t\t" << *hackingPointer << endl;
to
cout << "Value: \t" << 0 << "\t\t" << *(0x0044ff28) << endl;
Anyway, you have still succeeded to change value of memory where i is stored. But do not try this at home :-)
It is not permitted to change the values of a constant, in fact it's undefined behaviour so your program could do anything as a result.
In this instance it looks like your compiler optimised the read away at compile time because it knew the value is fixed. Lots of implementations might just crash when you try and change it, but you cannot and should not bet or rely upon the result of any undefined behaviour ever.