April 2004 - Posts

reopen fstreams, bug?

Re-open a fstream may fail... call clear() between close() and open()!

http://gcc.gnu.org/onlinedocs/libstdc++/faq/index.html#4_4_iostreamclear

posted by wenyang with 0 Comments

Suggestions about Improving Efficiency (gcc)

During the migration of CorbaFreeDynaMIT, we have noticed that some previous code may more or less decrease the efficiency. We are not talking about the algorithm at this time, though it should be more critical and significant.

Anyway, here are a few "rules of thumb" to avoid defect.

  • Remove unnecessary code from loop. For example, making a function call to check the size of a list during the loop can be taken out of the loop if the size is not going to change during the loop.
  • Use header files properly.To minimize the time we have to wait on the compiler, it's good to only include the headers we really need. Many people simply include iostream when they don't need to -- and that can penalize the runtime as well. (http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#10)
  • Use "\n" in output stream other than std::endl whenever possible. std::endl not only sends out a new line, but also flush the stream, sending out the output immediately, and the buffer is lost. The next time we add something to the stream, we have to re-allocate the buffer, which is time-consuming and ususally unnecessary.
posted by wenyang with 0 Comments

Notes to Migration of CorbaFreeDynaMIT (6)

Iterators

Iterators are a generalization of pointers: they are objects that point to other objects. In most situations we could instead use a pointer when an iterator is required, and even under some circumstance, the compiler will actually optimize iterators into pointers when creating the object codes. Iterators, however, are not necessarily implemented by pointers. For example, vector::iterator is not T*; string::iterator is not char*. Hence converting iterators to pointers is considered dangerous, and is likely to make our code broken.

The STL offers several predefined iterators, with different behavior. For example, the input iterators only guarantee read access. Selecting the correct type of iterators is one of the tasks we must face when migrating CorbaFreeDynaMIT.

Where does it occur? Most classes that use STL containers (vectors, pair, etc.) For example, in the getODID member function of class dtaMappingOD, using a writable iterator will cause an error: "invalid conversion from 'const idlOrigDestID* const' to 'idlOrigDestID*'."

Another example is we should not test whether a iterator is null pointer or not. The following code is invalid:

std::vector::iterator jIterator;

for( jIterator= iIterator->begin(); jIterator != iIterator->end(); jIterator++ )

{

if( jIterator ) { // i.e., if (jIterator != NULL )

// do something...

}

}
How to fix: Use const_iterator instead of the default iterator, and avoid unnecessary type conversion. Make sure we have include the proper header file, i.e.,

posted by wenyang with 0 Comments

Notes to Migration of CorbaFreeDynaMIT (5)

2.4 Stream formatting
The formating of stream is controled by so-called "flags". In the new c++ library, the data type for flags, defined as "__fmtflags" or "std::_Ios_Fmtflags" by the typedef statement, is in fact unsigned long integer.

For many member functions of the stream classes in STL, such as setf and flags, their arguments and/or return values are consequently of unsigned long type.

If we want to pass other types of data to those functions, we will have to cast (force type conversion) the data to unsigned long. In some situation, that might cause a problem.

Moreover, some functions in the stream classes change their definition. For instance, istream::unsetf no longer returns any value. We need to modify our code to adapt these changes.

Where does it occur? class Reader.

How to fix: We can either stick to our original data type, which is long, and use cast back and forth wherever it is needed, or change the function definition of our classes.

Changing public member function definitions for a class is error-prone and seldom suggested because it will change the interface of the class and thus might potentially affect all its clients, which make use of those public member functions.

Therefore currently we choose the first approach. We admit that conversion between unsigned long to long integers may cause some problem. In the long run we might still consider using the second approach.

posted by wenyang with 0 Comments

Notes to Migration of CorbaFreeDynaMIT (3)

2.2 Using std namespce

Since "std" is now a real namespace, required for many objects in GNU Standard C++ Library v3, or libstdc++-v3.

Most class or type identifiers and functions in the Standard Template Library (STL) are affected.

For example:

  • string, vector, list, map, multimap, etc.
  • i/o objects, e.g. cout, cerr, endl.
  • i/o formatting flags, eg hex, dec

Where does it occur? Most headers, source files. (*.h, *.cc, *.y)

How to fix: In most cases, we prefer adding the "std::" to wherever it is required. For example:

  • std::setiosflags( std::ios::showpoint | std::ios::fixed );
  • std::setprecision( 4 );
  • std::cout << std::flush;

This is the most explicit way. Also we need include the headers properly. For example, is required for std::cout, std::endl, etc.

We could also say "using namespace std;" somewhere before the call. This is the quick-butdirty fix, because it brings the whole of the std:: namespace into scope. Thus we should never do this in a header file, as every user of our header file will be affected by this decision.

posted by wenyang with 0 Comments

Notes to Migration of CorbaFreeDynaMIT (4)

2.3 From strstream to stringstream

The benefit of using stringstream include (a) we don't have to explicitly append ends to terminate the C-style character array, and (b) we don't have to mess with "freezing" functions or manage the memory ourselves. (We saw this in the original code of template std::string ToString( const TYPE &val ) from the file dtaSimulatedFlow.cc.)


Note: the stringstream.str() builds a string, not a char[] as was the case with strstream.str().
Thus we cannot to delete the buffer after use.

Where does it occur? Most classes that handles I/O, e.g. class Reader.

How to fix: std::strstream (similarly for ostrstream, istrstream) is replaced by std::stringstream (ostringstream and istringstream). Stringstreams are defined in the header .

In many cases, we simply use stringstream for output, thus we prefer std::ostringstream.

posted by wenyang with 0 Comments

Notes to Migration of CorbaFreeDynaMIT (2)

2.1 Deprecated headers

Table 1 shows some of the headers that may need to make changes. Although it is still possible to include those deprecated headers in g++ 3, it is strongly recommended that we use the new ones. Hence we switch to the new versions.

Deprecated headers are all located at the path /usr/include/c++/3.3.2/backward (at guitar).

Note that some headers listed in Table reftable:t1 do not belong to that path. This means that both versions should work fine at least in gcc 3.3.2, but still we prefer the new naming convention.

Where does it occur? Almost every header file (*.h) in CorbaFreeDynaMIT; many source files (*.cc and *.y).

Table 1: Deprecated headers and their recommended replacements

How to fix: Replace with the corresponding new headers.

posted by wenyang with 0 Comments

Notes to Migration of CorbaFreeDynaMIT (1)

Critical Changes of GCC (g++) from 2.96 to 3.3.2

Because of the following changes during the upgrade of gcc (from 2.x to 3.x), many source codes need modification:

  • The standard library is much more conformant. Codes or usages that do not follow the latest c++ standard may be unsupported in the new version of g++.
  • The std:: namespace is now a real namespace, not an alias for ::.
  • The standard header files for the c library don't end with .h, but begin with c (i.e. <CSTDLIB>rather than <STDLIB.H>). The .h names are still available, but are deprecated.
  • For ostream formatting, use the std::ios::fmtflags. The Integers are no longer valid.
  • <STRSTREAM>is deprecated, use <SSTREAM> instead. The strstream class is replaced by stringstream, which is more powerful and safer.
posted by wenyang with 0 Comments