Friday, November 25, 2016

Dealing with Opaque C Pointer in C++11

This post explains how to deal with opaque C pointer in C++11--read: how to interface with C in C++11.  This is important to know for those working on real world C++11 code because there are many C libraries out there that uses opaque pointer as their "interface" to other code, which in this particular case: C++11 application. It's also important to know for C++11 programmers because the way C++11 implement an opaque "interface" is different.

Now, let's detour a bit to "native" C++11 interface. The "native" C++11 interface is known as Compilation Firewalls, an opaque C++ interface "on steroid". These are the relevant articles on it:

Just read both of the links to learn more about C++11-style "native" interface. I'm not going to talk about it here.

Let's get back to our problem. Let's restate the problem into a more manageable question: How to wrap opaque C pointer into C++11 smart pointer (specifically unique_ptr)? Short answer: Use the  opaque C pointer object type as parameter to unique_ptr template and provide a custom deleter. That's it. If you understand the short answer, then you're done. If it's still unclear to you, then read on.

There are two kinds of unique_ptr template, one with only one template parameter (because the second parameter has default value) and one with two template parameters--see: http://en.cppreference.com/w/cpp/memory/unique_ptr. You need to use the unique_ptr template with two template parameters to wrap an opaque C pointer because you need to provide a custom deleter. A custom deleter is a function that finalize/deallocate the resources allocated by the unique_ptr constructor. Let's look at an example:

unique_ptr<FILE, int (*)(FILE*)> mFile{nullptr, closeFile};

The preceding code snippet shows the second unique_ptr template parameter is a function pointer. The function pointer is initialized with closeFile function name. In this case, the closeFile function pointer is the custom deleter. closeFunction() is a simple function which logs a message to the screen and then call fclose(), as shown in the following code snippet:

int closeFile(FILE* f) {
    cout << "Calling fclose()" << endl;
    return fclose(f);
}

You might be thinking how to obtain a valid FILE pointer in the first place, before disposing it with fclose(). Well, of course with a call to fopen(). This is how I do it:

public:
    explicit FileHandler (const char* path, const char* mode)
try:
        mPath{path}, mMode {mode}
    {
        cout << "FileHandler constructor" << endl;

        FILE* f = fopen(path, mode);

        if (f != NULL) {
            unique_ptr <FILE, int (*)(FILE*)> file{f, closeFile};
            mFile = std::move(file);

        } else {
            cerr << "FileHandler constructor: Exception! Unable to open file!" << endl;

            throw (FILE*) NULL;
        }
    } catch (FILE*) {

        throw (FILE*) NULL;
    }

The preceding code snippet shows that a valid FILE pointer is passed as parameter to the unique_ptr object that will manage the FILE pointer upon its initialization. Then, the object is moved to the equivalent class member which will manage the FILE pointer. You can clone the complete code at: https://bitbucket.org/pinczakko/custom-c-11-deleter

The sample shows how to wrap the opaque FILE pointer in a unique_ptr smart pointer. The FILE  pointer is an opaque "standard" C library pointer. Despite this, the technique is applicable to other opaque C pointer which usually acts as interface to a third party C library that you want to use in your C++11 application.

I hope this post is helpful to those looking to unleash the power of C libraries in C++11.

Monday, October 31, 2016

Cross Compiling Unicode Windows Application with Mingw-w64

Cross compiling Unicode Windows application in Linux is quite straight forward if you are using mingw-w64 cross compiler. All you have to do is turn on the -municode compiler switch. Other than that, you need to change your program entry point from main() to wmain() if your program is a command line program. I provided a complete sample code over at https://bitbucket.org/pinczakko/windows-event-object-test that you can read and use.

Now, let's look at the most important parts of the sample code with respect to Unicode support. First the CMakeLists.txt file. These are the necessary changes to support Unicode:
if (MINGW)
 message(status: " ** MINGW detected.. **")
 set(CMAKE_CXX_FLAGS_RELEASE "-municode ${CMAKE_CXX_FLAGS_RELEASE}")
 set(CMAKE_C_FLAGS_RELEASE "-municode ${CMAKE_C_FLAGS_RELEASE}")

 set(CMAKE_CXX_FLAGS_DEBUG "-municode ${CMAKE_CXX_FLAGS_DEBUG}")
 set(CMAKE_C_FLAGS_DEBUG "-municode ${CMAKE_C_FLAGS_DEBUG}")

# ..
endif()
The preceding code snippet shows the C++ and C compiler switch has been modified to use -municode if mingw compiler is detected.

Second, the entry point of the command line program is also modified:
int wmain( void )

The third change is the code also make use of wprintf() function in place of printf() in some places. This is one of the example:
wprintf(L"All threads ended, cleaning up for application exit...\n");
wprintf() is the "wide-character" version of printf(), well you could argue that you want to use the "tchar" version and so on. However, in this short article, the point is just to see how mingw-w64 support, I'm not trying to be extremely correct.

Thursday, October 27, 2016

What operator int() means in C++?

Short answer to the title of this post: It's a user-defined conversion to int.
Long answer: read on ;-).  The code below is a sample of the user-defined conversion. 
class MyClass {
public:
   //..
   operator HANDLE() const { return(m_hCJ); }
   //..


private: 
   HANDLE m_hCJ;          // handle to volume
   //..

};

The code above would return MyClass object's m_hCJ member value if a conversion to HANDLE type is requested. For example:
MyClass testClass;
HANDLE testHandle = testClass;
In the preceding code, testClass operator HANDLE() will be called (at runtime?) to return testClass.m_hCJ value.

For more comprehensive example and explanation, see: http://en.cppreference.com/w/cpp/language/cast_operator.

I brought this issue up because it uses the C++ operator keyword which is usually used for operator overloading. It could confuse those who hasn't seen C++ code that uses user-defined conversion.

Sunday, October 9, 2016

"Replacing" C++ Virtual Function with Template (and More)

There are several ways you can replace C++ virtual function with template. These are some related examples to accomplish the task:
Curiously recurring template pattern

http://stackoverflow.com/questions/16988450/c-using-templates-instead-of-virtual-functions#16988933

https://en.wikipedia.org/wiki/Barton-Nackman_trick

https://en.wikipedia.org/wiki/Bounded_quantification#F-bounded_quantification

https://en.wikipedia.org/wiki/Template_metaprogramming#Static_polymorphism

However, I found that the philosophy of using virtual function itself is quite "flawed" when one already use template in his/her C++ code. Why? Because, the Standard Template Library (STL) or Boost, or other C++ template library for that matter has a very different approach to programming than Object Oriented (OO) philosophy. Most if not all of them are meant to provide generic programming in C++ (as opposed to OO)--Generic as in ADA (https://en.wikibooks.org/wiki/Ada_Programming/Generics) and in general https://en.wikipedia.org/wiki/Generic_programming. I might be stating a hard line here, but nonetheless, that was what STL was written for. See for yourself what Alexander Stepanov (the most prominent STL author) wrote: http://www.stepanovpapers.com/notes.pdf.

What I stated in the previous paragraph meant that, in order to use template in a substantial C++ code base, we need a paradigm shift. Instead of looking at the solution as related objects, I think we need to look at the solution as "interfaces to generic algorithms". I think that you should gain more understanding of what I meant once you've read Stepanov remark in his notes. This is an important excerpt from his notes:
It is essential to know what can be done effectively before you can start your design. Every programmer has been taught about the importance of top-down design. While it is possible that the original software engineering considerations behind it were sound, it came to signify something quite nonsensical: the idea that one can design abstract interfaces without a deep understanding of how the implementations are supposed to work. It is impossible to design an interface to a data structure without knowing both the details of its implementation and details of its use. The first task of good programmers is to know many specific algorithms and data structures. Only then they can attempt to design a coherent system. Start with useful pieces of code. After all, abstractions are just a tool for organizing concrete code.
If I were using top-down design to design an airplane, I would quickly decompose it into three significant parts: the lifting device, the landing device and the horizontal motion device. Then I would assign three different teams to work on these devices. I doubt that the device would ever fly. Fortunately, neither Orville nor Wilbur Wright attended college and, therefore, never took a course on software engineering. The point I am trying to make is that in order to be a good software designer you need to have a large set of different techniques at your fingertips. You need to know many different low-level things and understand how they interact.
The most important software system ever developed was UNIX. It used the universal abstraction of a sequence of bytes as the way to dramatically reduce the systems’ complexity. But it did not start with an abstraction. It started in 1969 with Ken Thompson sketching a data structure that allowed relatively fast random access and the incremental growth of files. It was the ability to have growing files implemented in terms of fixed size blocks on disk that lead to the abolition of record types, access methods, and other complex artifacts that made previous operating systems so inflexible. (It is worth noting that the first UNIX file system was not even byte addressable – it dealt with words – but it was the right data structure and eventually it evolved.) Thompson and his collaborators started their system work on Multics – a grand all-encompassing system that was designed in a proper top-down fashion. Multics introduced many interesting abstractions, but it was a still-born system nevertheless. Unlike UNIX, it did not start with a data structure!
One of the reasons we need to know about implementations is that we need to specify the complexity requirements of operations in the abstract interface. It is not enough to say that a stack provides you with push and pop. The stack needs to guarantee that the operations are taking a reasonable amount of time – it will be important for us to figure out what “reasonable” means. (It is quite clear, however, that a stack for which the cost of push grows linearly with the size of the stack is not really a stack – and I have seen at least one commercial implementation of a stack class that had such a behavior – it reallocated the entire stack at every push.) One cannot be a professional programmer without being aware of the costs of different operations. While it is not necessary, indeed, to always worry about every cycle, one needs to know when to worry and when not to worry. In a sense, it is this constant interplay of considerations of abstractness and efficiency that makes programming such a fascinating activity. 
I need to emphasize the last paragraph of Stepanov note because I have just encountered a not so "miserable" failure very closely related to what Stepanov said in that paragraph. I need to cleanup some left-over code which supposed to provide abstraction for some sort of file system operation in two very different OSes. Unfortunately, the previous code failed "quite" miserably to provide good abstraction on the task, precisely because it wasn't designed from the ground-up on both OSes as Stepanov suggested. It was only designed from the ground-up to work well in one of them. Therefore, the design lean more to one of them. Fortunately, not all hope is lost because I think the task could still be salvaged through several iteration to fix the abstraction. I said "quite" miserably because the state of the matter could still be salvaged/fixed somehow. It's not a total disaster. I hope this is a good food for thought for C++ programmers out there.