Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Why these extra brackets?

This thread is locked; no one can reply to it. rss feed Print
Why these extra brackets?
Doctor Cop
Member #16,833
April 2018
avatar

I was searching on the GitHub for a simple compression library and I came across zip lib. Its a minimal wrapper on top of miniz library.

I have generated the object file successfully but when I came across examples then I got confused by this one.
I have an idea that they are used just to make code look better but can there be any other reason that the developers of zip used these brackets?

#SelectExpand
1struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w'); 2{ 3 zip_entry_open(zip, "foo-1.txt"); 4 { 5 const char *buf = "Some data here...\0"; 6 zip_entry_write(zip, buf, strlen(buf)); 7 } 8 zip_entry_close(zip); 9 10 zip_entry_open(zip, "foo-2.txt"); 11 { 12 // merge 3 files into one entry and compress them on-the-fly. 13 zip_entry_fwrite(zip, "foo-2.1.txt"); 14 zip_entry_fwrite(zip, "foo-2.2.txt"); 15 zip_entry_fwrite(zip, "foo-2.3.txt"); 16 } 17 zip_entry_close(zip); 18} 19zip_close(zip);

dthompson
Member #5,749
April 2005
avatar

You've basically got it: using arbitrary blocks like this is for readability, but also (in newer C standards) allows for tighter scoping.

buf ceases to be accessible after the block it's declared in has ended. As this is a relatively small piece of code, there isn't a huge benefit - but when working with huge functions, block-scoped variables are useful to prevent 'pollution' of the namespace, such that you don't accidentally reuse variables later on when you didn't mean to.

______________________________________________________
Website. It was freakdesign.bafsoft.net.
This isn't a game!

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Neil Roy
Member #2,229
April 2002
avatar

There's no real need to use them unless you don't want buf to be accessable outside of that scope.

As for ZIP file access, you can do that in Allegro with PHYSFS fairly easily, and then simply read and write files as you normally would. Depends on what you want it for of course.

---
“I love you too.” - last words of Wanda Roy

Chris Katko
Member #1,881
January 2002
avatar

For the 2 obvious reasons:

- Code is documentation. Writing code in logical blocks makes it clear the lines of code are related.

- RAII. RAII. RAII. And maybe some RAII.

In C++ (and even other languages), you make it so objects can never exist in an invalid state. You do this by creating an object with a constructor that has all the required data passed to it. A connection object, is given the URL, port, etc--all it needs. And it either FAILS (and yields a null, or throws an exception), or it's a real object.

The second step of RAII? Getting rid of the object when you're done. RAII returns a resource whenever the object is deleted. Like... when it leaves the stack.

void my_function()
   {
   //code
   
      {
      auto c = new connection("192.168.1.1", 80);
      c.send_data("Hello world.");
      } //closes connection. automatically. zero calls. 
//zero room for user error like forgetting
   
   //more code
   }

Other languages actually recognize this pattern so often that they make it an actual construct.

It's typically named with() or using().

with(auto c = new connection("192.168.1.1", 80))
  {
  c.send_data("Hello world.");
  }

Additionally, with/using also allows you to embed another scope. So:

with(auto c = new connection("192.168.1.1", 80))
  {
  // all of c's namespace is assumed / added to the block 
  // and tried for name resolution.
  send_data("Hello world."); // no need for c.
  }

That's really nifty when you have a really long one like

with(my.object.long.deference.c)
    {
    taco();  //calls my.object.long.deference.c.taco()
    }

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Doctor Cop
Member #16,833
April 2018
avatar

Thank you all for your responses, it's very helpful.

NiteHackr
I'm trying to use it to learn how to embed resources in one file and use those resources from my game.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Audric
Member #907
January 2001

Note how they use the pattern even when there is no local (block-scope) variable.

The zip_entry_open() / zip_entry_close() must be used as a pair, and every zip_entry_*() acts relative to the current entry. The zip_t structure must keep track of the context.

It would be more foolproof with a different API, but the API being how it is, I can understand how the coder used an unusual (?) coding style for these functions, in order to avoid errors.

bamccaig
Member #7,536
July 2006
avatar

Katko, your RAII is leaking like a sieve

It's not the RAII that is leaking. It's the lack thereof. :P In any case, it looks like the OP's snippet is C so RAII doesn't apply and will likely only confuse the OP.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Chris Katko
Member #1,881
January 2002
avatar

I wrote it at like 3 am, cut me some slack. ::)

The point still stands. I never said it was functional code.

You're using a GC

Which I am. ;D

bamccaig said:

OP's snippet is C so RAII doesn't apply and will likely only confuse the OP.

He said the construct. That construct exists in many languages.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs
"Political Correctness is fascism disguised as manners" --George Carlin

Doctor Cop
Member #16,833
April 2018
avatar

Thanks Edgar, now I know how embed resources into executable and now I just need to use Physfs to embed the resources into a separate file and link that file to the executable.

I am currently experimenting with stdio.h to use with my logic.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Just use 7Zip to make a zip file, then embed your object into your executable and use PhysFS to load it.

Edit
Katko that was bad code either way because if you're looking for certain effects in your destructor who knows when they would be called with a GC. The whole point of RAII is to clean up when you're done, not when the GC gets around to it.

Doctor Cop
Member #16,833
April 2018
avatar

I don't want to embed it into executable, I want to make a separate file which will have all the resources and I will load resources from that file.

That's what I'm trying to do.

Neil Roy
Member #2,229
April 2002
avatar

In my Deluxe Pacman 2 game, I have all my resources inside a ZIP file, complete with folders in it etc... to organize the data. I renamed the .zip extension as .pak, but you can use whatever you wish, doesn't have to be .zip. I then use Allegro 5 with PhysFS to load in my resources as needed like you would any other file. It's really quite simple.

I recently released the source code to my Deluxe Pacman 2 game, it is written in C (not C++), and uses only Allegro 5. If you're curious, you can download it. PhysFS is pretty simple to use thanks to Allegro 5.

It's at my website anyhow, the game and below the download for it, is the source code.

https://nitehackr.github.io/games_index.html

if you download the game itself, it contains the .PAK file which is the renamed ZIP, you can open it with something like 7ZIP easy and examine, extract all the data etc. It's all I did to create it.

---
“I love you too.” - last words of Wanda Roy

Doctor Cop
Member #16,833
April 2018
avatar

Thanks NiteHackr, I'll check it out once I successfully implement AI part in my game.
It's the point in which I had to refactor my code and implement observer style.

If only I had any clue what I'm doing ...

Any suggestions on good game design? Right now I'm following 'tutorial's point' and
GitHub Allegro Wiki.

From next time when I plan a project I will use DFD first and then code. This is my resolution for 2019!

princeofspace
Member #11,874
April 2010
avatar

As an aside, Python comes with a built-in zip encoder that I use for my projects. At the top of your script:

import zipfile

Then, when you get around to writing those files into a zip PhysFS can read, do this:

with zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED) as z:
   for f in [files to write]:
       z.write(f)

This has saved me a lot of time, because I can just keep a folder of project content and run a script every time I want to update what's in the program.

I've thought about uploading this to my github, but then I'd have to write documentation on it, which nobody likes to do.

Go to: