0

At the moment I'm on Windows and I work with WinAPI. I do not like try\catch so I use RAII, and this is construction which I usually use:

#define r_free(N, T, F, n)      \
   struct N {                   \
      T res;                    \
      N() : res(NULL) {}        \
      ~N() { if (res) F(res); } \
   } n

This macro allows me to write code such as below:

r_free(Hndl, HANDLE, ::CloseHandle, f);
DWORD err;

if(INVALID_HANDLE_VALUE == (f.res = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISING, 0, NULL))) {
   err = GetLastError();
   std::cout << err << std::endl;
   return err;
}

It works fine but not all WinAPI functions (which are required to free resourses) take one parameter. Maybe there is a way to edit macro above to fix this issue? What is better way to do this?

Asesh
  • 3,186
  • 2
  • 21
  • 31
  • 2
    Ditch the macro. Prefer a scope guard that accepts a lambda. – StoryTeller - Unslander Monica Jan 04 '18 at 07:21
  • Can you explain me what do you mean? –  Jan 04 '18 at 07:25
  • I would also say to simply explicitly default construct res() rather than provide NULL, – SoronelHaetir Jan 04 '18 at 07:32
  • @NickyC It's not duplication. I need tiny RAII for tests of my code snippets. –  Jan 04 '18 at 07:33
  • @SoronelHaetir, what do you mean? –  Jan 04 '18 at 07:36
  • 1
    You didn't read the linked to question close enough if you insist it's of no help to you. – StoryTeller - Unslander Monica Jan 04 '18 at 07:54
  • Scope guard can be useful for rarely used API but in general I prefer to create reusable wrapper classes for the resources I'm using. I have a generic Handle template so for new APIs I only have to write a deleter, which usually is a one-liner. At the calling site it's less code, much more readable than scope guard and I don't have to remember which function to call for freeing the resource. – zett42 Jan 04 '18 at 10:19
  • OK, I'll try to explain my trouble. Imagine, I have an idea and I want to test it without a large code wrappers. I'm sure the macro for this purpose is enough, isn't it? If I'll start a big project then of corse I'll use different techniques such as templates-lambda and etc. –  Jan 04 '18 at 10:53
  • OK, I'll try to clarify what you misunderstand. It is not a matter of "enough". It is a matter of good vs bad. Both template and lambda are basic building block of modern C++, suitable for all scales, from your test of small idea without a large "code wrappers" (what ever you mean), to big project with huge code base, enormous dependencies, and serious demand. Macro is just plain bad. It does not follow the rules of the language. It obscures reasoning of even a very small program of just a few lines. –  Jan 04 '18 at 13:10
  • @NickyC, well, we will assume that you have convinced me. Can you point me useful resources which help me to learn more about raii, lambda and etc? –  Jan 04 '18 at 13:24
  • https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list –  Jan 04 '18 at 16:19

0 Answers0