header image
INT*_C Macros
September 11th, 2012 under Programming. [ Comments: none ]

The header

1
stdint.h
stdint.h
defines loads of macros. As such it is an omnipresent header that is included in many other headers. Being a C99 header, some macros are disabled in C++. One example are the
1
INT8_C, INT16_C, INT32_c and INT64_C
INT8_C, INT16_C, INT32_c and INT64_C
macros. When looking at the header (see below) one sees that the macros can be enabled in C++ by defining
1
__STDC_CONSTANT_MACROS
__STDC_CONSTANT_MACROS
.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* The ISO C99 standard specifies that in C++ implementations these
   should only be defined if explicitly requested.  */
#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS
 
/* Signed.  */
# define INT8_C(c)      c
# define INT16_C(c)     c
# define INT32_C(c)     c
# if __WORDSIZE == 64
#  define INT64_C(c)    c ## L
# else
#  define INT64_C(c)    c ## LL
# endif
 
...
#endif
/* The ISO C99 standard specifies that in C++ implementations these
   should only be defined if explicitly requested.  */
#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS

/* Signed.  */
# define INT8_C(c)      c
# define INT16_C(c)     c
# define INT32_C(c)     c
# if __WORDSIZE == 64
#  define INT64_C(c)    c ## L
# else
#  define INT64_C(c)    c ## LL
# endif

...
#endif

When i tried this in some C++ file in my project, it didn’t fix the

1
error: ‘UINT64_C’ was not declared in this scope
error: ‘UINT64_C’ was not declared in this scope
. I realized that the header has already been included before I defined
1
__STDC_CONSTANT_MACROS
__STDC_CONSTANT_MACROS
. Due the the header guard the define has no effect. To fix this problem I simply undef the header guard.

1
2
3
4
5
#define __STDC_CONSTANT_MACROS
#ifdef _STDINT_H
# undef _STDINT_H
#endif
# include <stdint.h>
#define __STDC_CONSTANT_MACROS
#ifdef _STDINT_H
# undef _STDINT_H
#endif
# include <stdint.h>

Of course this trick does not work for all header but in the case of

1
stdint.h
stdint.h
it works because this header only defines macros.


On Destructors and Interfaces in C++
September 11th, 2012 under Programming. [ Comments: none ]

Comming from Java, I’m used to use interfaces (abstract classes with only abstract virtual methods. In C++ we only have the concept of abstract classes which are classes with at least one pure virtual function) in my type hierarchy.

This concept of an interface does not exist nor can or should it be used in a “copy-paste” manner. Let me give an example.

In Java we define an interface as:

1
2
3
public interface Interface {
   void method(int arg);
}
public interface Interface {
   void method(int arg);
}

So every subclass of Interface must implement/override method. In C++ this would look as follows when we “copy-paste” this:

1
2
3
4
5
class Interface 
{
  public: 
    virtual void method(int arg) = 0;
};
class Interface 
{
  public: 
    virtual void method(int arg) = 0;
};

Now, the C++ class cannot, by definition, function as a proper interface/abstract class. The problem is caused by the (here implicit) non-virtual destructor. So, as a result we cannot use the Interface as a base type pointer when we delete the object.

1
2
Interface* p = new Subclass();
delete p;
Interface* p = new Subclass();
delete p;

here the behavior is undefined according to the C++ standard. Normally though it would just call the implicit non-virtual destructor

1
Interface::~Interface()
Interface::~Interface()
.

To fix this we can either define an empty virtual destructor or declare the destructor as impure virtual.

So either

1
2
3
4
5
6
class Interface 
{
  public: 
    virtual void method(int arg) = 0;
    virtual ~Interface(void) {}
};
class Interface 
{
  public: 
    virtual void method(int arg) = 0;
    virtual ~Interface(void) {}
};

or

1
2
3
4
5
6
class Interface 
{
  public: 
    virtual void method(int arg) = 0;
    virtual ~Interface(void) = 0;
};
class Interface 
{
  public: 
    virtual void method(int arg) = 0;
    virtual ~Interface(void) = 0;
};

In the second case, it would be impossible to instantiate a subclass because the destructor of the subclass calls the destructor of its parents. Meaning

1
Interface::~Interface
Interface::~Interface
would be called but does not exists. Hence, it would result in an undefined reference error. A solution to this is to use an impure destructor [1]. This means we leave the pure virtual declaration of the destructor but still provide an implementation in the cpp file.

But in any case you must to tell the compiler that you want the destructor to be virtual.

References:
[1] http://www.gotw.ca/gotw/031.htm