What are these additional { } called (So I can do some googling about them) and what are they used for? I know this question might be dumb and maybe if I read some more about c++ I will occasionally learn what this is but right now I am focusing more on FLTK and I just want to know what these brackets are for. Thank you in advance!
It's the scope operator, a { marks the beginning of a scope, and a } marks the end. Resources that you didn't create using "new" will automatically be destroyed at the end of their scope.
ie:
1 2 3 4
{
int i = 0;
}
i = 10; //Error, i got destroyed because its scope ended.
In this case I have no idea what it is being used for since window_new is a global variable, and will be unaffected by the end-of-scope. Perhaps it's for readability?
Also, if you need to google them look for "C++ braces". I don't think they have a specific "C++ name".
Actualy, they do! They're called a "fake block", becouse they make the program htink it's some other block and therefore destroys all variables local to that block, while it's actualy the same block.
I've never made a new scope just to destroy some variables, I can't imagine I would unless I suddenly turned really fanatic about 'wasting' a couple bytes of memory, and if it is more then that perhaps you should start splitting the function up.
@Zephilinox I think one of the most common usage of this is when you need to enforce that mutexes are released properly in multithreaded programs. It can also be used in rendering functions to make sure the matrix stack is popped properly (Or in any program that has heavy stack usage for that matter).
@hanst I guess I should have said "a" scope operator.
I've never made a new scope just to destroy some variables, I can't imagine I would unless I suddenly turned really fanatic about 'wasting' a couple bytes of memory
Memory isn't the only resource. In general, objects should have as small a scope and life time as practically possible.
I know, I declare variables as late as possible in my function, but making a while new scope (and subsequently an extra tab of formatting) seems ridiculous 99% of the time
I've never made a new scope just to destroy some variables, I can't imagine I would unless I suddenly turned really fanatic about 'wasting' a couple bytes of memory
What if the object in question isn't a couple bytes long, but actually a couple hundred million bytes long? In fact, creating a new block is the only way to fine-tune the lifetime of standard containers.
Unless you allocate them dynamically, but that has problems of its own.
@Zephilinox I think one of the most common usage of this is when you need to enforce that mutexes are released properly in multithreaded programs.
Exactly. Auto-locking mutexes is IMO the single best thing about RAII. It's just an awesome way to guarantee correctness of thread synchronization.
regardless of the length, I can't imagine the function going on for any longer than needed, if it did I'm sure it could be split up, or the variable declared later.
Perhaps in a complex recursive function that goes quite deep? You wouldn't want objects on the stack for long, especially since the function addresses themselves will take up even more stack space.
Stream is a class that receives buffers from the application, does something with them, and writes the result to the file system. However, it has an internal buffer such that the state of the output file is undefined while the associated Stream exists*.
f() creates a Stream and writes to it, and once its done writing, it needs to read the resulting file.
The only two ways to do this is to create either a new function or a new block around the Stream. The generated code is likely to be identical, but a new block is just more convenient. Assuming worst case optimizations, the block is preferable because it doesn't involve creating a new stack frame and jumping to a different function.
* If this example sounds contrived, it's not. This is exactly how I wrote a class that implements a gzipped log. It was the most natural way to do it to maximize compression ratio.
Lacking the imagination to think of a good reason does not mean that a good reason does not exist; arguing from a position of ignorance is one thing, but when ignorance is the argument, it's time to stop.
For something less contrived, I often find myself doing this when prototyping
1 2 3 4 5 6 7
stuff;
stuff
{
std::lock_guard<std::mutex> lk(io_mutex);
std::cout << "some debug value " << var << " and another " << var << '\n';
}
more stuff;
of course these bits get replaced by proper logging library calls later on, but even in production I have a few blocks for the sake of locking hanging around.
I read somewhere that the extra brackets could be a trick to get destructors executed, where they normally wouldn't have been executed.
F.e. when the main is ended with exit() or abort() or terminate() ... if all the statements before are placed within additional brackets, then the destructors are called ... otherwise not.