Skip navigation.

Ambassador

The Royal C++ Embassy

Posts tagged with "c++"

Meeting with Bjarne Stroustrup

, , ,

Bjarne Stroustrup, the creator of the C++ language, was here in Oslo today and gave us a brief (5 hours?) talk about "The design of C++0x". It has helped us see the big picture and understand how standardization process is working. I got a "video" taken by him, accidentally, because my phone's camera was in video mode...

Read more...

Compilers and women - algorithms, functors, and smart pointers!

, , ,

STL enables us to write cleaner code and use a lot of ready to use algorithms. It sometimes get totally difficult to deal with algorithms and function adapters, though, and I think this is somewhat accepted by entire C++ community.

Read more...

Case insensitive UNIX = Mac OS X

, , , ...

I bought my Mac on a snowy Oslo night. We were in a hury. I didn't have a car and I asked favor of my friend to assist me bring this machine home...

Read more...

Simple member thunk for threads

, , , ...

When you want to create a thread, CreateThread will not accept a member function. It's important to have a thread as an object, I think it's also important to keep caller provided argument to CreateThread (without introducing a tuple that holds this valuable information and casting to and from void*, managing memory, etc). In addition to traditional techniques, we can use a small thunk, too!

Read more...

Synchronization doesn't necessarily mean locking

, , , ...

... or it may mean different kind of locking.

One of the biggest problems we deal today is correct thread synchronization. Thread synchronization itself is a maze. I would like to discuss my new proposed solution to a problem; reference counting smart pointer based lock-free implementation.

Read more...

Found an old project!

, , , ...

I have found my sample code about transparency and creating non-rectangular window shapes for Windows Mobile while digging archives.

Read more...

Did you hear that? Windows CE port is ready!

, , , ...

According to Opera Press Release, we have announced Windows CE SDK officially, as of yesterday.

I have started Windows CE port a few months ago. This official announcement made me very happy! I can now share my porting experience and excitement of rest of the team.

I would like to start with brief information about basic features we have today:
  • Features are equivalent with Linux SDK, so that a company can basically reuse its code on both platforms (Wow!)
  • Multiple tabs
  • One native window, multiple Opera windows
  • Widgets
  • User JavaScript, User CSS
  • AJAX
  • Wand
  • Bookmarks
  • Netscape Plug-ins
  • Multiple rendering modes (like Medium Screen, Small Screen, Desktop, etc)
  • Page Zoom
  • Native JSPlugin (basically; calling native code from JavaScript)
  • Many more, countless features!


It was a real effort
Starting a new port from scratch is difficult. Platform doesn't provide everything you need so you need to re-invent wheel. You need to know what does platform provide, what's the best way to utilize platform's API and not invent an equivalent one (which is potentially slower and less stable).

Preparing an SDK is slightly more difficult than preparing a full application. Customer of an SDK is usually another company, or say, another developer. These people will build their business upon something you do. They need full and correct documentation; what sort of functions does SDK provide, what are function arguments, return values, disaster scenerios... SDK should prefer telling caller that one of its functions is called incorrectly, instead of crashing whole application. SDK should be more stable, rock-solid than application itself.

SDK is a closed box but vendor should not make people to wonder its code (either just to see "how stuff works" or worse "fix a bug"). At this point, well documentation is crucial. Well testing is essential.

Testing an SDK is slightly different than testing a final product. Most users can test a final product, because, for example, it's got buttons, menus, help - something that they can understand and experience; this may not require any software engineering knowledge.

In SDK case, testers have to be experienced software engineers who can harness given library, who can guess pitfalls in software engineering and find potential crash-bugs. They can call functions in many weird ways, try to break it; like passing NULL to a function, where argument is intended to be an output buffer. Similarly, passing -1, calling from multiple threads, subsequent calls, out-of-memory conditions, etc.

We have added just one more platform, Windows CE, and hundreds of different embedded devices to platforms and devices Opera can run.

Software Development Kits, Libraries and Components

, ,

We all need some software development kits, libraries or some components (like COM or .NET's ones) to do the work we need.

Throughout our history, operating systems provided their APIs in C. C was a universal language for developers using any language. For instance, Perl people have written Perl modules consuming C libraries, C++ people did the same, so did Delphi guys. C is taught in universites (I'm not sure whether they still do this) and even a Delphi programmer (should?) knows C, just a little.

Companies have made up their own, internal libraries and managed these as assets. Some companies made products and provided their own APIs to third parties so that they can extend application's abilities or reuse the application in their own package.

Most of C++ libraries are just wrappers on some C functions. Because this seems like the best way, first of all. A native, pure C++ library can be very difficult to maintain and reused by third parties. There are lots of reasons, but let's start with some simple ones.
  • C++, in most cases, requires classes' declarations to be shipped (header files, containing class declarations).
  • C++ is more type-safe than C, so vendor should provide more information about the class, try to stick on type safety or use casts, while C API can just return a "handle" (void*, may be?) and "implicitly cast it".
  • Compiled C++ object code is less portable/compatible across different compilers (name decoration, or, mangling? vtable layout? multiple inheritance layout? exceptions?)
  • One little change in a class changes its layout, so vendor should send updates to customers and all customers should rebuild their projects, re-deploy to their customers.
  • Everybody has his/her own coding style and may not like others' style.
  • There are bunch of well-known techniques that are then named "patterns" (somebody once came and said "so you used Factory pattern?", I didn't know what was factory pattern, I thought that approach fits best to my design).
  • Not all compilers support whole ISO/IEC 14882 standard, so vendor should consider obeying standard and compromise some cool features, like exceptions and templates (which could also allow customers to see majority of the library code).

C APIs, on the other hand, have some good sides:
  • Return a handle, request a handle - no need any implementation detail.
    typedef void*    HDATA;  // some data "handle"
    
    HDATA CreateData(const wchar_t** pwszArguments, int iArgs);
    int DecodeData(HDATA h, wchar_t* pbuf, int cchbuf); // use handle returned by above function
    

  • No name decoration. So "void foo()" will be "foo", unlike its decorated version C++, like "??QV?foo?WZW". Therefore, it's far more portable, as there is no standard way for name decoration in ISO/IEC 14882.
  • No "exception" or run-time polymorphism concern, therefore more portable.
  • All languages can access simply, as C is more solid from standard point of view.
  • Everybody can read, or at least can use, C code.
  • In most cases, installing dynamic library solves problem, without rebuilding everything. It's not always the case, however.
  • Few terminologies, no "containment", "aggregation", "inheritance", "some really cool pattern", making C easier to write and reuse.
  • Many more.

This is not a C++ bashing, but these are the facts. Object-oriented programming is not the purpose, it's a technique that we use to solve some sort of big problems. We should not mix the purpose with the tools we use to achieve the goal; they are distinct subjects.

A vendor can provide a C API, but use C++ code in its implementation. This is a pretty common technique, which is still being used today.
class DataClass
{
public:
    void foo();
    int bar();
    DataClass* baz();
};

HDATA CreateData(const wchar_t** pwszArguments, int iArgs)
{
      HDATA h;
      DataClass* pcls;
      // do something with pcls
      h = (HDATA)pcls;
      return h;  // return pointer to a DataClass object.
}

int DecodeData(HDATA h, wchar_t* pbuf, int cchbuf)
{
      DataClass* pcls = (DataClass*)h;
      return pcls->DecodeData(pbuf, cchbuf);
}

This technique prevents any confusions, both in development and consuming a library.

Polymorphism
This is an important subject, as in some cases customer may want to alter some particular behavior of a particular type and API supports polymorphism to allow customer's code to override some behavior (like in bad old MFC).

In C++, we have two types of polymorphism, as you may already know; the run-time polymorphism, through virtual functions and compile time polymorphism through templates.
template<typename T>
class SomeClass
{
public:
     bool some_method(T& t)
     {
         // do something
     }
     void foo(T& t)
     {
        // ...
     }
};

typedef std::vector<int> MyVectorType;
MyVectorType g_vec;

void foo(int i)
{
     SomeClass<MyVectorType::value_type> sc;
     some_method(g_vec[0]);
}

The std::vector itself was polymorphic enough, but having one additional delicate sample is harmless.

The well-known inheritance based run-time polymorphism can be slightly complicated, too - never mind how complex will objects look like in memory.
class Base
{
     virtual void foo() = 0;
     virtual void bar();
public:
     void f();
};

class Derived
{
     // implicit virtual
     void foo()
     {
     }
public:
     void f();
};

void test(Base* pbase)
{
   pbase->foo();
   pbase->bar();
   pbase->f();
}

void polycall()
{
   Derived d;
   test(&d);
}

Hmmm...


Microsoft has asked me "what is a virtual function" during an interview. I have given the explanation in the ISO/IEC 14882 - simply, call goes to final overrider - but in my opinion, the correct answer is "depends on how 'deep' you know". For above example:
  • Base::foo is virtual, so calls can propagate to final overrider, which is Derived::foo, in our case. Note that Derived::foo is an implicit virtual function. If a base class declares a function with exact name and argument list and exact or a covariant return type, the function is virtual in derived classes, regardless of virtual qualifier in declaration of function in derived class.
  • Base::bar is virtual, so calls can propagate to final overrider, too, but Derived does not override Base::bar, therefore call does not propagate Derived.
  • Base::f is not virtual, so calls can't propagate and all Derived::f does is "hiding" base's method. In this case, test function will call Base::f and not Derived::f.

This technique was quite heavily used in famous MFC library. The former, template based (static?) polymorphism is heavily used in WTL, which generates tighter and smaller code.

Addictions, habits and mentality
There are people who like their wrist watches to be on their left wrist and there are who like otherwise. Some like red cars, some black, some white. Much like different tastes in other areas in our lives, we have habits and "tastes" in software world, too! Not everybody likes templates, not everybody likes multiple-inheritance, etc. When it comes to C++, number of tastes and ways increase mind bogglingly. This is where customer starts disliking, hating and swearing vendor or author, architect of API, and it goes until Bill Gates. Never mind that almost every vendor has its own string class that is not compatible with other string classes.
// Vendor code
class DataAcquirer
{
public:
    // can conflict with customer's code?
    DataAcquirer& operator<<(int i);

    // can customer refuse/modify this data?
    virtual void OnDataArrived(const Data& rdata);

    // yet another string class... perhaps, this is "more efficient"...
    VendorString GetDataSource();

    // did they override operator new, too??
};

// too complicated for average C++ programmer.
// may be nightmare for new graduates!
template<typename T, template<class, class> class TSomeContainer, typename TTraits = SomeTraits>
class SomeTemplate : public SomeBase<T, TSomeTraits>
{
   TSomeContainer<T, LibraryAllocator<T> > m_arr;
public:
   typedef typename SomeBase<T, TSomeTraits>::some_type some_type;
};


As a conclusion, I happen to believe making a C++ SDK and happy customers seems rather difficult.

COMponents
I've always said that COM (or an equivalent way) was a perfect way to develop and use SDK. Vendor provides a (bunch of) DLL(s), customer either plugs component or writes some abstraction over it or just use it as-is, by modifying a few properties. They are cute, nice, solid black boxes. Talking about COM;
  • Customer usually does not need a header file, compiler can import type library from DLL.
  • There is no non-standard C++ name mangling.
  • Uses reference counting, less pain to manage memory (we have smart pointers!).
  • It forces "pimpl idiom" on those who want to override particular behavior of component.
  • It has a set of standards (well, COM is a set of standards)
  • C users can (re)use, too (through vtable?)


Stupidity can be better
I believe that a library better be stupid. With stupid, I mean, it should provide details and not an abstraction salad or trying to do everything for me. Because this may leave small room for enhancements. For example, if you take standard C library, it does not try to do everything, but provides some functions, which you can use together and end up with an abstraction. Library provides low(er)-level processing, customer (or user) uses them together and ends up with an abstraction layer. Alternatively, vendor writes a complicated function that has various parameters and flags that behaves different for each case. This is, however, rather less flexible than lower-level functionality.

Clear documentation and one consistent one baseline
Documentation is what customer needs. Customer has to know which conditions are error, which are successful, who is allocating buffers, whether call is thread-safe or does it acquire any lock, etc. In Win32 API, for example, there are some functions where caller provides a NULL pointer to learn how much memory should be allocated to store information. So customer makes two calls; first, to get buffer size (check return value, too, it may be a completely different error!) and second, to do the actual work. This is not a consistent design, in my humble opinion.

Win32 API is very well documented. There are some COM interfaces, some components that are almost not documented, no sample, no nothing. I remember I have written wrappers around various DLLs to intercept calls and try to see how those particular objects work.

Conclusion
In my humble opinion, C is still the best programming language to write APIs.

"I cannot find import library for my GUIDs!"

, , ,

Visual C++ has got a keyword, specifically designed for COM projects; the "__uuidof". So, for example, if you want to instantiate a class with CLSID_Application and you need ISomeInterface, you'd normally do:
ISomeInterface *psi;
psi = NULL;

HRESULT hr = CoCreateInstance(CLSID_Application, NULL, 
                              CLSCTX_INPROC_SERVER,
                              IID_ISomeInterface,
                              (void**)&psi);

If you get a link error for IID_ISomeInterface and CLSID_Application despite the fact that you have essentially tried to link all import libraries suggested in any piece of documentation, try:
HRESULT hr = CoCreateInstance(__uuidof(Application),
                              NULL,
                              CLSCTX_INPROC_SERVER,
                              __uuidof(ISomeInterface),
                              (void**)&psi);

Trick is that this operator returns GUID of given expression, if any provided. Of course, I am talking about "normal" scenerios, like:
#if defined(__cplusplus) && !defined(CINTERFACE)
  MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
  IUnknown
  {
  public:
    BEGIN_INTERFACE
    virtual HRESULT STDMETHODCALLTYPE QueryInterface
            (REFIID riid, void **ppvObject) = 0;
    virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
    virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
    END_INTERFACE
  };
#else   /* C style interface */
  typedef struct IUnknownVtbl
  {
    BEGIN_INTERFACE
    HRESULT (STDMETHODCALLTYPE *QueryInterface)(IUnknown *This,
             REFIID riid, void **ppvObject);
    ULONG (STDMETHODCALLTYPE *AddRef)(IUnknown *This);
    ULONG (STDMETHODCALLTYPE *Release)(IUnknown *This);
    END_INTERFACE
  } IUnknownVtbl;

  interface IUnknown
  {
    CONST_VTBL struct IUnknownVtbl *lpVtbl;
  };
#endif

The "MIDL_INTERFACE" macro specifies GUID for the interface (which is IID_IUnknown).
Or (stolen from Microsoft's sample, see critics below):
//  expre_uuidof.cpp 
//  compile  with:  ole32.lib 
#include  "stdio.h" 
#include  "windows.h" 

[emitidl]; 
[module(name="MyLib")]; 
[export] 
struct  stuff  { 
    int  i; 
}; 

 int  main()  { 
    LPOLESTR  lpolestr; 
    StringFromCLSID(__uuidof(MyLib),  &lpolestr); 
    wprintf_s(L"%s",  lpolestr); 
    CoTaskMemFree(lpolestr); 
}

Found a few problems with the sample:
1. C or C++ code cannot be compiled with a lib, but can be linked. So instead of "compile with", it should be "link with"
2. #include "stdio.h" does not seem good. It's supposed to be #include <stdio.h> (mind <>, please)

Or, alternatively, if you import:
#import "SomeLibrary.dll" no_namespace raw_interfaces_only

In fact, as far as I remember, when you import, you can specify "named_guids" option to import directive, which will generate CLSID_SomeStuff in type library header. However, I don't remember whether this requires import library at link stage.

It's hidden out there!

, , ,

Abruptly starting subject; overloads are not inherited, if derived class has a method with the same name - they are hidden.
#include <iostream>

using std::cout;
using std::endl;


class X
{
public:
        int Add(int)
        {
                cout << "X::Add(int)" << endl;
                return 0;
        }
        int Add(X&)
        {
                cout << "X::Add(X&)" << endl;
                return 0;
        }
};

class D : public X
{
public:
        int Add(char)  // Hides base's Add method(s)
        {
                cout << "D::Add(char)" << endl;
                return 0;
        }
};

int main()
{
        X x;
        x.Add(x);   // OK: X::Add(X&)
        x.Add(3);   // OK: X::Add(int);
        D d;
        d.Add('c'); // OK: D::Add(char)
        d.Add(1);   // Error: overloads are hidden
        d.Add(x);   // Error: overloads are hidden
        return 0;
}

Derived classes have a bad attitude of hiding its bases' methods. It may sound weird, ugly and disturbing, but imagine otherwise; base class has changed, author decided to add another overload which has an argument type that is causing an unintentional conversion with the type you pass or by-passes your intentional conversion, for example?

If you really really want to reuse base's methods, here are tricks:
  • Use "using" declaration to explicitly declare that derived class introduces base's types and methods to its declerative region (e.g. using X::Add). This will enable all overloads in base class to be visible to callers of derived.
  • Explicitly refer to base's scope in the caller (e.g. d.X::Add(x) calls X::Add(X&))
  • Implement overloads in derived, call base's methods.
  • Templatize Derived::Add (e.g. template<typename T> int Add(T t) { return X::Add(t); } - you can specialize this as well!)

My heart beats for "using" and templatizing, although this is not the way I would prefer.

If I were to design this base class:
  • Add would be a template.
  • Since this class is designed to be a base, it could look like:
    class D;
    
    template<typename T>
    class X
    {
    public:
            template<typename U>
            int Add(U u)
            {
                    T* pt = static_cast<T*>(this);
                    // force derived class to implement AddItem for each U
                    return pt->AddItem(u);
            }
    };
    
    // char, specialization.
    template<>
    template<>
    int X<D>::Add<char>(char c)
    {
            // add it
            return 0;
    }
    

  • If it's not a template, it would probably have private pure virtual functions that needs to be implemented by derived types. (I've just heard some said "private pure virtual function? I thought we're talking about recent British-Pakistan cricket game!".)

    class X
    {
    virtual int AddChar() = 0;
    virtual int AddInt() = 0;
    // .. others
    public:
    int Add(char c)
    {
    return AddChar();
    }
    };

If I were to write derived class:
  • There will not be inheritance, but "pimpl".

    class D /* : public X */
    {
    X* m_px;
    public:
    int Add(char c)
    {
    return m_px->Add(c);
    }
    };
  • If there is an inheritance, I would use "using" to declare base's methods
  • or, alternative to above case, I would use template methods and may be their specializations.

This all depends on design.
Download Opera, the fastest and most secure browser
November 2009
S M T W T F S
October 2009December 2009
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30