Archive for the ‘visual c++’ Category

Size of enumeration type in C++

Sunday, May 24th, 2009

In C++ enumeration is used to define set of named constants. Each enumeration is a distinct compound type (enumerated type) and is subject to all rules of type system defined in C++ language. Internally, enumeration is represented with so called underlying type. The C++ Standard ISO/IEC 14882:2003 (Section 7.1/5) specifies it as follows:

The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration.

It is not specified which particular integral type is used to represent an enumerated type. Given that number of bytes representing fundamental integral types is implementation defined in C++ and only sizeof(char), sizeof(signed char) and sizeof(unsigned char) are guaranteed to be always 1, value reported by sizeof operator applied on enumeration is considered as implementation defined as well. Sometimes one may need to control size of enumerated type in memory, for instance to serialise and de-serialise objects easier.

Some compilers allow to specify underlying type of enumeration. For instance, Microsoft Visual C++ provides dedicated language extension:

enum Color : unsigned char
{
   red, green, blue
};
// assert(sizeof(Color) == 1);

Obviously, this technique is not portable across other implementations of C++ language.

In order to solve this problem in portable way, a simple class template can be defined:

template <class E, class T>
struct enumeration
{
    typedef T type;
    typedef E enum_type;

    enumeration()
        : e_(E())
    {}

    enumeration(E e)
        : e_(static_cast<T>(e))
    {}

    operator E() const
    { return static_cast<E>(e_); }

private:
    T e_;
};

The enumeration class can be used as a portable way to wrap any enumerated type and to specify (or limit) amount of bytes used to represent it. It is also interchangeable with actual enumeration being wrapped:

#include <cassert>

enum Color { red, green, blue };

int main()
{
    enumeration<Color, unsigned char> color(blue);
    assert(sizeof(color) == 1);

    Color c = color;
    assert(c == blue);
}

It’s also possible to provide default argument for template parameter T specifying underlying type of wrapped enumeration. For instance, if most constant values in a project range from 0 to 255, default type value of T can be unsigned char.

Hi COM! How’s it going?

Saturday, May 9th, 2009

In June 2000 at PDC in Orlando Microsoft announced .NET Framework project. Shortly after that developers concentrated around products and technologies made by Microsoft started debate on what’s the future of software development. One of questions and quite obvious was: So does this mean that COM is dead?. A few months later, Don Box addressed that concern in his extensive article Is COM Dead?:

It depends on what your definition of COM is. COM is many things to many people. To me, COM is a programming model based on integrating components based on type. Period. This was COM’s primary contribution to the field of component software, and that contribution has changed the way millions of programmers build systems today.

Don is right and the answer is historically and technically correct, however this is an indirect answer that didn’t cheer up at all. Given the closing words in that article:

(…) CLR provides significant benefits to developers who are using COM today. Virtually all aspects of the COM programming model have survived (…) I look at the CLR as breathing new life into the programming model that I’ve spent the last seven years of my life working with, and I know there are other programmers out there who share this sentiment.

overall conclusion becomes more an abstruse philosophy than binary answer. What about all these cryptic terms of Component Object Model technology made by Microsoft, like OLE, ActiveX, DCOM and other? Silent.

Nearly ten years later, developers are still asking the same question (a few days ago, similar discussion took place on ACCU mailing list) about COM. Alf. P. Steinbach gave an interesting answer that, however, sounds very similar to the one given by Don Box:

COM is one of the few successful C++ component technologies, if not the only one (depending on one’s definition of “successful (…) Some reduced and slightly modified versions of COM are used in e.g. Linux user interface and in Firefox browser (XCOM). Original COM itself is however a Windows-specific technology. But while it’s necessarily used to interface to the operating system and at higher levels in e.g. scripting, it’s my impression that it’s now now not much used as a general C++ component technology, i.e., that use of COM is something forced, not something desired and freely chosen.

Even though both are similar, it’s been decade since the question was asked for the first time and now we have 10 years of experience based on observations what has changed after .NET was thrown on the marked. The managed baby seems to be winning the market of Microsoft-oriented (not only, though) developers and users. COM is widely used as components of Windows systems and other already existing software but are new COM servers and objects still being developed? Or, has it started to suffer of COM programmer species extinction?

The www.microsoft.com/COM/ website confirms that:

Microsoft recommends that developers use the .NET Framework rather than COM for new development.

In my humble opinion, Mr. COM is like an old veteran, alive, but most of his comrades-in-arms have died, so he usually goes to pub alone.

Detecting Visual C++ version in NMAKE makefile

Sunday, March 29th, 2009

Traditionally when building GDAL/OGR, GEOS or libLAS using NMAKE users specify version of Visual C++ compiler being used as value of MSVC_VER macro. This macros is not required but it’s recommended, so NMAKE can compose best possible set of compilation and linking flags for particular version of Visual C++. For instance, command specifying Visual C++ 8.0 (Visual Studio 2005) looks like this:

nmake -f makefile.vc MSVC_VER=1400

Recently, I hacked libLAS makefiles (and GEOS makefiles too), so Visual C++ version can be determined (semi-)automatically. NMAKE 1.62 or higher reports its version as value of _NMAKE_VER macro. The solution is to defined compiler version based on version of NMAKE tool:

Update 2009-04-03: Added _NMAKE_VER number 9.00.21022.08

!IF "$(_NMAKE_VER)" == ""
MSVC_VER = 4.0
!ERROR *** Prehistoric version of Visual C++
!ELSEIF "$(_NMAKE_VER)" == "162"
MSVC_VER = 5.0
!ERROR *** Prehistoric version of Visual C++
!ELSEIF "$(_NMAKE_VER)" == "6.00.8168.0"
MSVC_VER = 6.0
MSC_VER = 1200
!ERROR *** Prehistoric version of Visual C++
!ELSEIF "$(_NMAKE_VER)" == "7.00.9466"
MSVC_VER = 7.0
MSC_VER = 1300
!ELSEIF "$(_NMAKE_VER)" == "7.10.3077"
MSVC_VER = 7.1
MSC_VER = 1310
!ELSEIF "$(_NMAKE_VER)" == "8.00.50727.42"
MSVC_VER = 8.0
MSC_VER = 1400
!ELSEIF "$(_NMAKE_VER)" == "8.00.50727.762"
MSVC_VER = 8.0
MSC_VER = 1400
!ELSEIF "$(_NMAKE_VER)" == "9.00.21022.08"
MSVC_VER = 9.0
MSC_VER = 1500
!ELSEIF "$(_NMAKE_VER)" == "9.00.30729.01"
MSVC_VER = 9.0
MSC_VER = 1500
!ELSE
MSVC_VER = 0.0
MSC_VER = 0
!ENDIF

Later macros MSVC_VER and MSC_VER can be used to report Visual C++ version:

!IF "$(MSVC_VER)" == "0.0" && "$(MSC_VER)" == "0"
!MESSAGE *** Cannot determined Visual C++ version
!ERROR *** Aborting make job
!ELSE
!MESSAGE *** Using Microsoft NMAKE version $(_NMAKE_VER)
!MESSAGE *** Using Microsoft Visual C++ version $(MSVC_VER)
!MESSAGE *** Using Microsoft C/C++ version $(MSC_VER)
!ENDIF

This is not a rocket science, but it seems to work well and it frees users from manual specification of Visual C++ version. I’m not sure how the NMAKE version numbers vary across Visual Studio versions and builds. It would be good collect these version numbers to make the solution reliable. So, I’d be thankful if readers using Visual Studio 2002, 2003, 2005 and 2008 or newer :-) could report their NMAKE versions directly to me or post them as comments below.

Building PostGIS using Visual C++

Sunday, March 29th, 2009

I don’t like MinGW. I’ve been dreaming about building PostGIS using Visual C++ – the native development toolset for Windows platform – without being forced to install Unix-like environment inside Windows. Finally, I’ve got motivated enough and decided to make my dreams reality, so here is the story.

First, I collected all run-time dependencies required by PostGIS. I intentionally used the word run-time to indicate I’m not going to install MinGW neither Cygwin or any other GCC-for-Windows package. GNU make is also not required.

I use PostGIS source code from trunk in the Subversion repository.

Dependencies

There are only 3 software packages required:

  1. PostgreSQL 8.3.6official Win32 binaries and source code
  2. GEOS – build from sources, it’s safe to grab SVN trunk
  3. PROJ.4 – also build from sources and also from SVN trunk

I installed the PostgreSQL 8.3.6 without PostGIS extensions, as I’m going to provide my own :-), using default location c:\Program Files\PostgreSQL\8.3. The source code of PostgreSQL 8.3.6 went to d:\dev\postgresql\postgresql-8.3.6.

Short note on directories layout using for projects downloaded directly from repositories. Root path of source tree of each project have the same layout: D:\dev\PROJECT\_svn\trunk. For Visual Studio projects, these paths are defined as macros in postgis.vsprops (Visual C++ Property Sheet), so it should be easy to redefine them without any need to hack other project settings like Additional Include Directories and others.

(more…)

Visual C++ Toolkit 2003 still in use

Monday, September 22nd, 2008

Charles Petzold's TattooIn 2004, Microsoft published Visual C++ Toolkit 2003 – full version of Visual C++ 2003 optimizing compiler (version 1310) available free of charge. It was the first free, good and almost complete implementation of C++ programming language by Microsoft. It is quite old but still used by many developers.

The Toolkit is fairly complete, but you can not avoid a few hacks if you want to use it :-) So, I’ve decided to collect them all in one place to help building projects like GEOS, libLAS or GDAL/OGR with the Visual C++ Toolkit 2003.

Installation

First, installation of the following packages is required:

  1. Microsoft .NET Framework SDK 1.1
  2. Microsoft Platform SDK for Windows Server 2003 R2
  3. Microsoft Visual C++ Toolkit 2003 (no longer available from Microsoft website, just be persistent cuiling for it)

Hacks

This is list of hacks like installation of missing components and fixing a project makefiles:

  1. The .NET Framework SDK 1.1 installation (listed above) is required in order to get C Run-Time libraries installed: msvcrt.lib and msvcrtd.lib. The .NET SDK installer will copy these files (and a few other components) to directories located in:

    C:\Program Files\Microsoft Visual Studio .NET 2003
    
  2. Surprisingly, import library for C++ Run-Time Library msvcp71.dll is not included in the Visual C++ Toolkit 2003 distribution. Missing files can be downloaded from CERN server: msvcprt.lib and msvcprt.def. Copy them into

    C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib
    
  3. The Toolkit does not include lib.exe utility – Microsoft Library Manager. Fortunately, lib.exe is just a simple wrapper on Microsoft Incremental Linker – link.exe. So, in your NMAKE makefiles replace lib.exe (or lib) command with:

    link.exe /lib
    

    Alternatively, you can build custom lib.exe wrapper using lib.c program. Recently, I’ve fixed NMAKE makefiles of GEOS (r2190) and libLAS (r876) projects using the former option.

Environment

Most of articles about Visual C++ Toolkit 2003 and Platform SDK installation procedure suggest to permanently update environment variables like INCLUDE, LIB and PATH. Personally, I don’t like this approach. Instead, I write a simple SET_MSVC71.BAT script which I execute in console window before I run NMAKE to build a software project using Visual C++ Toolkit 2003.

The script I use consists of three commands:

@echo off
CALL "C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\SetEnv.Cmd"
CALL "C:\Program Files\Microsoft Visual C++ Toolkit 2003\vcvars32.bat"
CALL "C:\Program Files\Microsoft.NET\SDK\v1.1\Bin\sdkvars.bat"

Copy this script to location that is available from the PATH.

Sample build – libLAS

Below, a few simple steps are presented of using Visual C++ Toolkit 2003 and environment configured as presented above to build libLAS project. The same procedure should work for projects like GEOS or GDAL/OGR.

  1. Run Command Prompt (cmd.exe)
  2. Configure environment by executing SET_MSVC71.BAT script:

    C:\> SET_MSVC71.BAT
    

    Check if basic commands are available: cl.exe, nmake.exe, link.exe.

  3. Go to libLAS source code directory:

    C:\> cd dev\liblas\trunk
    
  4. Run NMAKE command to build libLAS library and utilities:

    C:\dev\liblas\trunk> nmake /f makefile.vc
    

Good luck!

std::basic_istream fixed in VC++ 9.0

Tuesday, January 29th, 2008

Stephan T. Lavavej from the Visual C++ Libraries Development Team confirmed that the bug I’ve reported recently about incorrect cast in the input operator implemented in the std::basic_istream class has been fixed. New corrected implementation is available in the C++ Standard Library shipped with latest version of the Visual C++ 9.0 compiler from the Visual Studio 2008.

A bug in std::basic_istream from Visual C++

Wednesday, January 23rd, 2008

Update: I submitted this problem to the Microsoft Connect and the Feedback ID is 323765

I believe I found a bug in Visual C++ implementation of the C++ Standard Library (AFAIR, it’s provided by Dinkumware,Ltd.). This is my first trove of that kind in Visual C++, thus I should exclaim Hurray! ;-). The C++ library discussed here is shipped with Visual C++ 8.0 compiler from the Visual Studio 2005 Professional.

Shortly, in the std::basic_istream class, implementation of input operator overloaded for unsigned long with Microsoft specific modifier __w64 consists of incorrect cast from reference to non-const to unsigned long, a nonreference type – rvalue.

(more…)