December 2006 - Posts

STL.NET : Why ?

For the experienced C++ programmer, STL is one of essential toolkits, and its absence under .NET 2.0 was a significant disappointment. VC++ 2005 fixed that by providing an STL.NET library as solution that combine STL templates and .NET generics. STL.NET expected to utilize developer's experiences in native STL to .NET world.  Templates are a C++-only concept that does not exist past compile time, whereas generics are a .NET concept that is maintained in the compiled assembly and available to all .NET languages. STL.NET implements the collections as C++ template classes that are also .NET reference types that implement the generic ICollection interface. Apart from a few differences in the way a STL.NET collection is declared, which relate to the syntactic differences between C++/CLI and standard C++, using a STL.NET collection is exactly the same as using the same STL collection.

Why should the Visual C++ programmer prefer STL.NET? And isn't that going to separate our programs from the rest of the .NET languages? These are valid questions, and deserve a response. Stanley Lippman asnwered like below:

One answer is extensibility. The original design pattern of STL, invented by Alex Stepanov, separates algorithms and containers into separate domain spaces. Thus, one can add to the set of algorithms that apply to all containers, or, one can add to the set of containers to which the algorithms can be applied. The Generic library is a more conventional container model. And that leads us to a second response.

A second answer is unification. The working C++ programmer has built up an expertise with this library as well as an existing body of code. We would like to not only provide a migration path for existing code, but also for existing expertise as well. If you have previously depended on the STL in your C++ programming, and it is difficult to imagine a working C++ programmer who does not depend on the STL, its absence under .NET feels like a significant loss—at least that has been my experience. It is a concern raised by many expert C++ programmers whom I have spoken to, and who have expressed reservations about migrating to .NET.

A third answer is performance. But C++ programmers are stereotyped as being . . .  well, obsessive about performance issues, and so I'll just mention it here in passing—we'll get to it in one of the later articles.

I am one of possible thousand people out there who wait the article. Performance always a good topic to discuss, right? I plan to have my own performance test for STL.NET to share with you later. Have a nice weekend geeks !.

Thx - R.A.M

Share this post: | | | |

Vector structure

In C++ STL, vector class is a template class of sequence containers that arrange elements of a given type in a linear arrangement and allow fast random access to any element. We speak of a vector as a container because it contains other objects. All of the objects in a container must have the same type. They should be the preferred container for a sequence when random-access performance is at a premium. Vector must has single type and each of which has an associated integer index. As in string, STL takes care of memory usage associated with storing all the elements. When we use CL.EXE with /MT, /MTd, /MD, or /MDd, we can also gain advantages from thread-safety effect point of view. The way to initialize a vector in C++ is easy as following:

vector<T> v1;       // vector that holds objects of type T; Default constructor v1 is empty
vector<T> v2(v1);   // v2 is a copy of v1
vector<T> v3(n, i); // v3 has n elements with value i
vector<T> v4(n);        // v4 has n copies of a value-initialized object

Note: put #include<vector> and using std::vector before.

Vector operation in native STL is:

v.empty();        // Returns true if v is empty; otherwise returns false
v.size();         // Returns number of elements in v
v.push_back(t);   // Adds element with value t to end of v
v No;            // Returns element at position n in v
v1 = v2;          // Replaces elements in v1 by a copy of elements in v2
v1 == v2;         // Returns TRue if v1 and v2 are equal
!=, <, <=,
>, and >=         // Have their normal meanings


With Visual C++ 2005, the Standard Template Library (STL) has been re-engineered to work under the .NET Framework. Stanley Lippman article was the first in a series of articles on STL.NET, a re-engineering of the STL implemented using both the CLI generic and the C++ template mechanisms. STL.NET is new to Visual C++ and only shipped in Visual Studio 2005. I agreed with him that STL.NET is a very exciting library addition, and I hope you will agree too. Let see MSDN example of STL.NET:

#include <cli/vector>
#include <algorithm>
void stlCollection() { vector<String^> ^svec = gcnew vector<String^>;
svec->push_back("Pooh");
svec->push_back("Piglet"); svec->push_back("Eeyore");
svec->push_back("Rabbit");
// generic algorithm: sort sort( svec->begin(), svec->end() );
Console::WriteLine( "Collection holds {0} elements: ", svec->size() ); for ( int i = 0; i < svec->size(); i++ ) Console::WriteLine( svec[ i ] );
    // generic algorithm: find
    vector<String^>::iterator iter = find( svec->begin(), svec->end(), "Pooh" );

    if ( iter != svec->end() )
    {
         // no downcast required ...
         String ^item = *iter;
         svec->erase( iter );
    }

    // generic algorithm: remove ...
    remove( svec->begin(), svec->end(), "Rabbit" );

    Console::WriteLine( "\nCollection holds {0} elements:", svec->size() );
    IEnumerator<String^> ^is = svec->GetEnumerator();
    while ( is->MoveNext()) Console::WriteLine( is->Current );
}

Ok. Before you finish read this posting, be carefull with vector structure in .NET System.Windows namespace (WindowsBase.dll). It is a different vector animal. It is used by WPF to represents a displacement in 2-D space. Any public static members of vector type are thread safe but any instance members are not guaranteed to be thread safe.

I hope you enjoy STL as I do.

Thx - R.A.M 

Share this post: | | | |

C/C++ Inline Assembly

Inline assembly code in C/C++ doesnt require separate assembly and link steps. It can use any C/C++ variable or function name that is in scope. Inline assembly is also special-purpose tool. If you plan to port an application to different type of machines (IA32, IA64), you'll probably want to place machine-specific code in your separate module. Other people found useful to have inline MASM codes for:

  • Writing functions in assembly language (portable)

  • Spot-optimizing speed-critical sections of code (in addition to /O1, /O2, or /Ox)

  • Making direct hardware access for device drivers

  • Writing prolog and epilog code for "naked" system calls


Lets see a sample from MSDN. You can compile it using cl /Zi /Fa CodeName.cpp .

#include <stdio.h>

int power2( int num, int power );

int main( void )
{
     printf_s( "3 times 2 to the power of 5 is %d\n", \
     power2( 3, 5) );
}

int power2( int num, int power )
{
      __asm
     {
         mov eax, num                            
         mov ecx, power                 
         shl eax, cl                            ; EAX = EAX * ( 2 to the power of CL )
      }
    
     // Return with result in EAX
}

Note that int type supported by mov operand. Using /Fa, you C++ compiler can generate exactly the same MASM code for us (CodeName.asm).

; mov eax, num
mov eax, DWORD PTR _num$[ebp]
; mov ecx, power
mov ecx, DWORD PTR _power$[ebp]
; shl eax, cl
shl eax, cl

The inline version of the power2 function refers to its arguments by name and appears in the same source file as the rest of the program. This version also requires fewer assembly instructions. Because the inline version of power2 doesn't execute a C return statement, it causes a harmless warning if you compile at warning level 2 or higher. The function does return a value, but the compiler cannot tell that in the absence of a return statement. We can use #pragma warning to disable the generation of this warning. Becareful !

Share this post: | | | |

Happy New Year... New Frameworks !!

History of Windows programming:

1985. C/C++. Win32 API.
1992. C++. MFC.
1998. VB6. COM.
2001. C#, VB.NET, J#, C++/CLI. WinForm.
2006. C#, VB.NET, C++/CLI. WPC (Windows Presentation Foundation).

As you can see, number of languages, APIs/frameworks, and programming models are tripled in the last 3 years. This year (2007) we may have many options to develop Windows application. As usual, higher abstraction will gain us productivity and lower one will provide us control to the low level resources.  In WPF, we dont deal with window procedure, window messages, message loop and dispatcher. No more! We deal with objects that we can be written in any .NET languages or XAML. Both sides, Win32 or WPF has certain benefits for us but every thing will depend to our needs. Tools are created to help us realize our goals and dont be trapped in term of new framework features. Once we jump into real product development, complexity will always come.

I personally suggest Windows developers to keep learning unmanaged API because it will help us to understand all. Combining managed and unmanaged frameworks/APIs knowledge will always be the best choices. We can utilize the productivities offered by managed frameworks and still hold the control to the lower level resources. Using this way, developers will understand that developing Windows application will never be easy. Nothing will be easy to develop good products, doesn't it?

The general trend in software development is people prefer to choose the easier way to develop application. Yes, that is natural. But after all, no good products can be done easily. As INDC Geeks, you should set your mind that nothing will be easy in order to learn more. Let me give you simple example, say it, "chatting". For some people who dont see the complexity, chat client is easy to build. If you use LCS, you can reuse some "managed API" to build new chat client using connect to "managed RTC API". But when business analyst expands the requirement to utilize user experience like in real live chat, it become complex in term of UI. Just with simple internal requirement like "minimize memory usage for client process or use custom compression for messages", you will scream to ask help from unmanaged world. Virtualization like in .NET always brings productivity but to be managed by other codes (CLR) rises other expense. Good developers must understand both worlds, managed and unmanaged. In such a way, you always have two choices when developing applications.

You may argue me that "too much to learn". But trust me, that is our world. If you have decided to be developer for your entire career, thats the only way we have to follow. Almost 8 months since Raffy was born I decided to learn back fundamental CS knowledge. I read Knuth, Cormen, Sedgewick, and Levetin books for algorithm. Also C/C++ books for Win32, STL and ATL, but I still think that is not enough. I should be able to manually optimize codes instead of depend 100% to compilers (Zeddy will make better compiler in the future!). Thats why I learn MASM again from Irvine, Brey and Mazidi books. I have to spend many more years (no end) to finish all together with my "design patterns and concurrency/parallelism" passions. In our world, we cant stop learning because "old things are too much" and "new things always come". Keep that spirit with us in this new year moment. Define your specialities and keep focus in exploring them. Later, time will make you an expert.

Welcome to 2007 and stay tuned !!!

Share this post: | | | |