ISVis Adaption Study

advertisement
ISVis Adaptation Study
Spencer Rugaber
Peter Calvert
Barrie
Philip Norton
Michele Biddy
SUMMARY
1. PURPOSE
The Interaction Scenario Visualizer (ISVis) tool was written approximately 10 years ago
to analyze execution scenarios of legacy software. The goal of this tool was to aid those
in charge of maintaining, upgrading, designing, or testing a given program, so that they
could have a better understanding of the architecture of the system. It does this by
identifying interaction patterns in the event traces of the subject program and allows the
user to construct scenarios with the available files, classes and functions from the given
subject program. The user can create these scenarios by grouping interactions together to
create higher level behavioral abstractions by selecting program information from the
graphical interface. ISVis has a wide range of features including:







Analyzing event traces simultaneously with multiple traces in the same
program.
Having multiple views.
Having the ability to portray global overviews of scenarios.
The abstraction of actors through hierarchies and components.
Filtering of Interactions.
Interaction Patterns
Saving and retrieving analysis
ISVis was originally written in an older version of C++, the persistence portion was
written using Rogue Wave, the User Interface portion was written using the Motif toolkit
and the platform for it to run on was a Solaris machine. Since the program has since
become dated with the standardization of C++, upgrades to Motif and Rogue Wave, and
the need for portability for this program on different platforms, it was deemed important
to make the necessary upgrades to achieve these goals. After an analysis of ISVis, it was
decided that we would tackle these goals in two stages. The first stage was to upgrade
ISVis and get the program to run, on the same platform it was originally written for.
Upon that accomplishment, the second stage was to make ISVis portable to multiple
1
platforms, including Windows. We organized a group consisting of four including the
team lead, and set out to reach our goals over Fall Semester 2006.
2. ISVIS DATA
C++
The original ISVis program was written in an older version of C++ code and since then,
C++ has been standardized, creating differences between the older non-standard version
of C++ and the new standardized version of C++. Because of these differences, ISVis
would not compile using the current compilers that are ANSI C++ compliant, requiring
the code to be upgraded. This section outlines a plan of action to upgrade all ANSI C++
inconsistencies that are currently in the ISVis source code. Any existing code that does
not comply with the ANSI C++ Standard will be replaced by the equivalent functionality
that is present within the C++ ANSI Standard. The table in Appendix A is a complete list
of the known inconsistencies between the non-ANSI C/C++ code and ANSI C++. This
list will be used as a guide to detect any inconsistencies in the ISVis C/C++ source code
and will aid in finding the solutions.
The table below is a summary of the initial compile errors for all categories. Since our
first goal is to get ISVis to compile and run, our first priority is to get the entire critical
list of compile errors fixed and then later, work on getting the non-critical errors fixed.
Category
Make File
Motif
C++
Rogue Wave
Totals
Critical
6
4
78
188
276
Non-Critical
0
6
92
102
200
Totals
6
10
170
290
476
Current Inconsistencies found in ISVis
The following is a list of ANSI C++ inconsistencies that are located in the ISVis source
code and number of each inconsistency. This is not a complete list, because the
compilation stopped on some files due to the high number of errors, but this will give us a
good indication of the type of errors that we will find.
Source File
Actor.c
Occurrences Found
line 51: Error: A typedef name cannot be used in an elaborated type specifier.."actor.H"
Actor_list-view.c
line 402: Error: Incorrect access of a member from const-qualified function. (2)
line 51: Error: A typedef name cannot be used in an elaborated type
specifier.."view_manager.H"
line 122: Error: Cannot return const DotActor* from a function that should return
2
DotActor*."program_model.H"
Disk_file.c
Event_writer.c
Main_view.c
line 447: Error: i is not defined."actor_list_view.C", (11)
Compilation aborted, too many RW Error messages
line 59: Error: Could not open include file "event_writer.H".
line 85: Error: The function "initTimestamp" must have a prototype
"program_model.H", line 122: Error: Cannot return const DotActor* from a function that
should return DotActor
"main_view.C", line 84: Warning: String literal converted to char* in initialization. (23)
Program_model.c
"program_model.H", line 122: Error: Cannot return const DotActor* from a function that
should return DotActor*.
"program_model.C", line 1028: Error: Incorrect access of a member from const-qualified
function. (12)
Scenario.c
Compilation aborted, too many Error messages.
"program_model.H", line 122: Error: Cannot return const DotActor* from a function that
should return DotActor*.
Error: Cannot use const Trace* to initialize Trace*.
Error: Cannot use const Scenario* to initialize Scenario*.
Error: Cannot use const TraceImpl* to initialize TraceImpl*.
Error: Cannot use const InteractionImpl* to initialize InteractionImpl*.
Scenario_view.c
"scenario_view.C", line 85: Warning: String literal converted to char* in initialization.
(47)
"scenario_view.C", line 329: Error: i is not defined. (16)
Compilation aborted, too many Error messages
Static_analyzer.c
"static_analyzer.C", line 87: Error: Only a function may be called. (6)
"static_analyzer.C", line 171: Error: Incorrect access of a member from const-qualified
function. (2)
Error: Only a function may be called. (3)
Trace.c
Compilation aborted, too many Error messages.
"program_model.H", line 122: Error: Cannot return const DotActor* from a function that
should return DotActor*.
Error: i is not defined. (15)
Trace_analyzer.c
Error: Cannot use const Trace* to initialize Trace*.
Error: Could not open include file <ctoken.h>.
"program_model.H", line 122: Error: Cannot return const DotActor* from a function that
should return DotActor*.
Error: Cannot use RWCString to initialize int.
View_manager.c
Error: Only a function may be called. (3)
Error: Could not open include file <bstream.h>
3
Error: Cannot return const DotActor* from a function that should return DotActor*
Error: Cannot use std::basic_ifstream<char, std::char_traits<char>> to initialize int.
Error: The operation "int >> ViewManager" is illegal.
Error: Incorrect access of a member from const-qualified function.
Warning (Anachronism): Formal argument 2 of type extern "C" void(*)(int) in call to
std::signal(int, extern "C" void(*)(int)) is being passed void(*)(int).
Warning (Anachronism): Formal argument 2 of type extern "C" void(*)(int) in call to
std::signal(int, extern "C" void(*)(int)) is being passed void(*)(int).
Warning: String literal converted to char* in initialization. (32)
Xapp.c
Error: best is not defined. (4)
Error: Cannot assign const char* to char*.
Comments
This is not a complete list of all the C++ errors, because some of the source files stopped
the compilation process due to a very large number of errors. An initial analysis of the
compile errors indicates the following:





It seems that that are quite a few initialization errors that are minor
corrections, like leaving off the “int” when using i. (40)
Lots of warnings about string literals converted to char” in initialization.
(55)
There are errors because of the use of “const” in the code. (9)
The following files are not being included because they couldn’t be
opened, like bstream.h, ctoken.h, and event_writer.h. (3)
There seems to be a recurring problem in several file compiles that use
program_model.h that has an error with returning a constant DotActor.
Some of these issues will take further analysis and investigation to uncover the problems,
like why those header files aren’t being opened, and some will not take very long to fix. I
think that there are some issues that will span Motif, C++ and Rogue Wave, due to the
ANSI C++ standardization.
Estimated Time
Best Guess: 30 hours //depending on how many more errors we uncover along the way.
4
Rogue Wave
Rogue Wave is a third party library that is used extensively through out the ISVis
program. The version of Rogue Wave that was used to create ISVis is no longer
available and could either be updated or replaced by something else.
Current Rogue Wave functionality in ISVis
The following is a list of Rogue Wave functions that are used within the ISVis source
code. A short description of each Rogue Wave element is given as well as an alternative
from the C++ standard library.
Element
RWDEFINE_COLLECT
ABLE
RWCString
RWBoolean
RWCollectable
RWFile
RWCTokenizer
Description
Macro for assigning a
classID to a class
String manipulation class
Boolean wrapper
Abstract
class
for
collectable objects
ClassID wrapper
return type for function that
defines the number of bytes
needed to store an object in
a binary file
Virtual output stream
Virtual input stream
Bespoke wrapper class that
uses Rogue Wave hash
tables
Rogue Wave singly linked
list container
HashTable where only one
item of a given value will be
accepted
Rogue Wave hash table
container
container for storing pairs of
hash keys and values
Rogue Wave doubly linked
list container
file encapsulation
splits a string into tokens
RWTPtrOrderedVector
RWBitVec
vector container class
resizable bitfield
RWClassID
RWspace
RWvostream
RWvistream
TPtrHashMap
RWTPtrSlist
RWTPtrHashSet
RWTPtrHashTable
RWTPtrHashDictionary
RWTPtrDlist
Alternative
See [1]
Instances
16
std::string
bool
See [1]
587
139
85
See [1]
See [1]
4
49
std::ostream
std::istream
See [2]
46
45
40
std::list<T>
180
See [3]
8
See [3]
38
See [3]
209
std::list<T>
43
std::fstream
maybe use stringstream,
or just roll our own
std::vector
std::vector<bool>
or
13
18
20
27
5
std::bitset
[1] No direct alternative
[2] Bespoke classes that are used with Rogue Wave
[3] There is no hashing functionality in the C++ Standard Library (see below for options)
Comments
It seems that there are three main areas where the Rogue Wave Libraries are used:
1) Persistence
2) Container classes
3) Strings
Taking these in reverse order:
3) The RWCString is used extensively throughout the whole ISVis program, I suspect the
reason for this is that when the program was originally written std::string was not readily
available and using RWCString was a better alternative to using char arrays and the
associated issues of bounds checking etc. The functionality of RWCString is very similar
to that of std::string, but there is a little extra functionality that is not available in
std::string. However, as the additional functionality is not used within ISVis then this is
not a major concern.
Whilst tedious it will be fairly trivial to change the functionality from RWCString to
std::string. This should be a case of determining which of the std::string functions
provides the same functionality to that of the RWCString, and then performing a find and
replace on the source code.
Estimated Time to complete: 5 hours
2) As the C++ Standard Library has an extensive range of container classes, finding
alternative should be fairly simple. However there may be an issue. There is no hashing
functionality within the C++ Standard Library. Whilst the std::map provides similar
functionality to a hash table it is not clear what the performance implications would be of
using std::map instead of a hash table. A possible alternative is to use hash_map, which
is a common - but non-standard – extension to the standard library. This would introduce
a dependency, however if most compilers support this extension it may be feasible.
My understanding is that in all but pathological cases hash_map will give better
performance that std::map. However, it is very difficult to provide a metric for how
much of a performance difference there will be.
Whilst hash_map is included in most compilers libraries as an extension, the location
seems to be different for each.
For example in gcc you need to include
<ext/hash_map.h> and hash_map is in the __gnu_cxx namespace, whereas for Microsoft
Visual Studio you have to include <hash_map.h> and hash_map is in the stdext
namespace. This could be overcome with some convoluted use of #ifdef and typedef.
6
I think the best solution is code it so that it is simple to switch between map and
hash_map and once the code is stable run some performance experiments to see if there is
a significant performance difference between map and hash_map.
To replace the Rogue Wave container classes with the STL equivalents are mainly a
matter of find and replace after determining the equivalent functionality. Extra
consideration is required for replacing the hashing functionality as described above.
Estimated time for completion: Hashing 10 hours
other container classes 6 hours
1) There is no direct alternative to the persistence functionality that is available in Rogue
Wave. However, as all this seems to provide is a framework which a programmer can
use to implement persistence within a program, then it should not take a huge amount of
effort to modify the code to use what is available within the C++ Standard Library.
Rogue Wave includes an abstract class RWCollectable that all classes that should be
persistent need to derive from. Each class then needs to override the saveGuts and
writeGuts functions with class specific information to allow the class to be serialized.
Most of the necessary functionality has already been written for use with Rogue Wave. It
will just be a matter or replacing the high level framework that Rogue Wave uses with
our own bespoke version.
Estimated time for completion: 20 hours
Motif
Because ISVis was written with an earlier version of Motif than is currently available,
changes had to be made to ISVis to account for these differences. Starting in Motif 2.0,
The Open Group cleaned up many of the Motif API’s. The public API’s (intended for
application development) was left as is, but the private API (needed by widget writers)
was heavily modified. Prior to the 2.0 release, there were 2 types of symbols, public
(prefixed by Xm) and private (prefixed by _Xm). In the 2.0 release, a new symbol type
Xme was introduced and most _Xm symbols were renamed to Xme.
The ones left as _Xm are internal to the library.
Several symbols (ex: EditDone, EditError, etc.) have been moved to the public header file
Xm/Xm.h from their original location in the private header file Xm/TestStrsoP.h. This
can cause problems in applications and libraries that use these symbols themselves that
results in a namespace conflict at compile time due to the redefinition.
Toolkit and Widget class changes
Listed below are the specific Toolkit and Widget class deprecations from Motif 1.2 to
2.1. Inspection of the code indicates that none of these changes will have an impact on
ISVis.
7

Renditions and RenderTables: The XmFontList data type and associated functions
are now deprecated, replaced by a new entity called the XmRendition.

VendorShell: The VendorShell has the new resources XmNbuttonRenderTable,
XmNlabelRenderTable, and XmNtextRenderTable that replace the deprecated
XmNbuttonFontList, XmNlabelFontList, XmNtextFontList resources.

Label: The XmFontList resource is deprecated and is superseded by the
XmNrenderTable resource. The same is true for LabelGadget.

MainWindow: The routine XmMainWindowSetAreas() is deprecated. The
XmNcommandWindow, XmNmenuBar, XmNmessageWindow, XmNworkWindow,
XmNhorizontalScrollBar, XmNverticalScrollBar resources should be set directly
using the standard Xt mechanisms.

MenuShell: The XmNbuttonFontList and XmNlabelFontList resources are
deprecated, and are replaced by the XmNbuttonRenderTable and
XmNlabelRenderTable resources. Also deprecated is the XmNdefaultFontList
resource, but there is no replacement XmNdefaultRenderTable resource.

Scale: The XmNfontList resource is deprecated, and replaced with the newer
XmNrenderTable resource

Text and TextField: The XmNfontList resource is obsolete and is replaced by
the XmNrenderTable resource.
ISVis Motif dependencies
The following is a list of the Motif function calls made in the ISVis application along
with the source files containing Motif dependencies:
Files with Dependencies:
actor_list.c
io_shell.c
main_view.c
mural.c
scenario_view.c
xapp.c
Function/Macros/Class
xmFormWidgetClass
xmDrawingAreaWidgetClass
xmTextWidgetClass
XmTextInsert
XmTextGetLastPosition
XmTextSetEditable
XmTextGetString
XmTextSetString
XmTextSetCursorPosition
xmPushButtonWidgetClass
xmSeparatorWidgetClass
xmCascadeButtonWidgetClass
xmSeparatorWidgetClass
XmDrawingAreaCallbackStruct
8
xmToggleButtonWidgetClass
XmStringFree
XmString
XmStringCreateSimple
XmStringGetLtoR
XmProcessTraversal
XmMenuPosition
XmCreateSimplePopupMenu
XmCreatePulldownMenu
XmCreatePopupMenu
XmCreateOptionMenu
XmCreateMenuBar
Review of code
Initial review of the ISVis Motif code does not indicate any apparent issues with
migrating from Motif 1.2 to Motif 2.1. ISVis does not make use of any symbols changed
or moved from Motif 1.2 to 2.1. In addition, the Motif classes, functions and macros used
do not appear in the list of changes made by The Open Group for Motif 2.1. Ultimately, a
compile of ISVis using Motif 2.1 will reveal any issues involved with the port from 1.2 to
2.1 but initial indications are that they should be minor.
Initial Code Compile Results
Appendix B shows the current compile time errors with all the UI source code as it
pertains to Motif. These were a result of the code being written in non-ANSII C++ and
using Motif 1.2 while the compile was an ANSII compliant compiler using Motif 2.1.
Time Estimates
Looking at the output above, many of the issues are compiler warnings, indicated
syntactical confusion on the part of the compiler. There are a limited number of errors
that relate directly to Motif itself. These errors and warnings appear to be syntax related
as a result of the ANSII compiler change as well as the upgrade of Motif from 1.2 to 2.1
and do not appear to be a result of using Motif functions/widgets/gadgets/etc which are
no longer available. Therefore, it is estimated that it will take 20 hours of time to correct
these errors so that a clean compile can be made as it relates to Motif.
As of 10/26/06, all Motif related compile time errors have been corrected except for any
that are Rogue Wave dependent (i.e. utilize RW strings). All code has been checked into
developer branch and merged into the main branch.
Cross Platform Interoperability
9
The first issue to address with cross platform interoperability is if we just wish to run
ISVis on other OS’s or do we want to actually port the code to compile and run on
another OS.
The former is a more straightforward task in that products such as Cygwin, VMWare,
VirtualPC, can be used. Information on these tools is located here:
http://www.cygwin.com/
http://www.vmware.com/
http://www.microsoft.com/windows/virtualpc/default.mspx
Porting to another platform requires significant more work. Automatic porting tools can
be used to accomplish this task as well (as proclaimed in the journal article
http://www3.interscience.wiley.com.gtel.gatech.edu:2048/cgibin/fulltext/105559946/PDFSTART?CRETRY=1&SRETRY=0
read for today’s meeting.
One tool which proclaims to perform this task is MKS Toolkit for Enterprise Developers,
http://www.scl.com/products/mks/datasheets/tkedev.html
which allows you to develop and migrate Motif, X Windows, 3-D, and OpenGL
applications written in C, C++, or Fortran, as well as non-graphical applications and
scripts, over to Windows.
It highlights the following as its capabilities:







Migrate existing UNIX C, C++, and Fortran applications to Windows.
Access remote UNIX, Linux, and Windows systems.
Integrate applications with Windows technologies.
Web enable applications.
Single desktop solution for native Windows and UNIX, Linux, and Windows
development.
Easily package and deploy applications.
Integrated cross-platform build environment.
Another porting tool that is available is BX/WIN SDK Porting Kit. This tool proclaims to
allow the porting of UNIX and Motif based applications over to Windows.
http://www.scl.com/products/ics/motif/builders/bxwin
This tool contains support for UNIX SVR4, Berkeley extensions, POSIX, X11R5 and
Motif API’s as well as C and C++. A partial list of API’s supported by this tool is:






UNIX SVR4, Berkeley extensions, POSIX, X11R5 and Motif API support
fork() and exec()
C, C++ support
Shared memory, semaphores, and message queues
Multi-user file I/O with locking on all Windows NT file systems
Extensive UNIX-to-Windows NT security mapping
10



Networking support via Berkeley sockets
Hard links
Curses
Further investigation of these tools will be needed prior to attempting to utilize them.
Porting “by hand” will require that a Motif Toolkit for the OS/platform being ported to
will be needed and the source code compile on each individual platform. Toolkits such as
OpenMotif, QT, etc. will require investigation.
References
Overview of the Motif 2.1 Toolkit - Changes in Motif 2.1
http://docs.mandragor.org/files/Operating_systems/Linux/Motif_Programming_Manual_
en/ch-3.fm.html#3638
Motif 1.2 Porting Guide
http://techpubs.sgi.com/library/manuals/3000/007-3951-001/pdf/007-3951001.pdf#search=%22Motif%20API%22
Solaris
The following forms are the system function call and library API call used in the ISVis
program.
System function call
exit();
Statistics
15 calls in 6 files
Library API function calls
abs()
assert()
atoi()
fabs()
floor()
gettimeofday()
longjmp()
printf()
signal()
sprintf()
strcpy()
strlen()
strncpy()
Statistics
2 calls in 1 file
1 call in 1 file
6 calls in 3 files
2 calls in 1 file
1 call in 1 file
4 calls in 1 file
2 calls in 1 file
8 calls in 1 file
6 calls in 1 file
16 calls in 4 files
5 calls in 2 files
27 calls in 4 files
6 calls in 1 file
3. METHODS & RESULTS
11
C++
In order to accomplish this, I first investigated the differences between the older version
and the new standardized version of C++. I installed Winscp so that I could transfer files
between my pc and the Lennon server and I used SecureCRT so that I could remotely
access the Lennon server in order to compile the source files. I initially tried to setup a
Solaris machine at work to use, but found that it was much easier to just remotely access
Lennon with SecureCRT. I installed Eclipse on my PC in order to edit the sources files
and set up a directory using Tortoise to access the CVS repository. After the Makefile
was edited so that we could compile each source file individually, I was able to assess the
actual critical compile errors and the warning errors. There were initially one hundred
and twelve critical compile errors and seventy-two warnings. It was decided that I would
fix the critical compile errors first, in order for us to get a clean compile, and then I would
concentrate on the warnings.
As I fixed the critical compile errors, I kept records on each source file that contained
information about the progress of the compile errors as I methodically fixed each one.
The records contain the original compile errors and the errors that I fixed along with a
reference code. The reference code corresponds to the table in my proposal that lists the
C++ and ANSI C++ differences. I referenced each known difference between the older
C++ code and the ANSI C++ code in my proposal with a number, starting with one and
ending with forty-eight. The number is highlighted in red and listed at the top of each
entry in the table. The numbers flow sequentially, so looking them up in the table will be
simple. I then referenced the appropriate reference number in my source file documents
to indicate exactly what caused the error to occur. For example, one fix might indicate a
reference # 35. If you go to my proposal and look in the table and look up number 35,
you would see that the error was caused by a string literal being constant. I have included
a link to my C++ page on our website that contains all my documents pertaining to the
C++ work that I did on this project in the References section of this report.
After all the critical compile errors were taken care of, it was now time to get a clean
compile of ISVis. Peter checked in his code and stubbed out his methods, added the g++
compiler and we got the program to compile. We initially were using the cc compiler on
Lennon to compile our source code and then we incorporated the g++ compiler. With the
introduction of this additional compiler, my warning messages grew on one compiler and
shrank on the other. The messages were completely different on each compiler. So, again,
I kept a running document for each compiler and listed the original warning messages
and the final compile message. I was able to fix all the warnings, except for two on the cc
compiler.
Rogue Wave
The initial stage in replacing Rogue Wave was to research into what the functionality of
Rogue Wave was, and what would be required to removed it. I was already fairly
familiar with the standard template library (STL) and the functionality that it provided, so
12
I was fairly certain that it would provide most of the functionality required with regards
to replacing the strings and container classes as these are standard structures in computer
science. The area which would prove to be more of an issue was going to be the
persistence. I found a good website stating how to serialize C++ objects which indicated
that it was possible and it appeared to fit in well with how it was done using Rogue
Wave. Along with this another task I worked on was to try and get the current code to
compile with updated Rogue Wave libraries on lennon, I found there were library flags
that were supposed to tell the Sun CC compiler about the Rogue Wave libraries to use,
however, these seemed to have limited effect. As Rogue Wave was going to be removed
anyway, there didn’t seem to be much point in spending too much effort in getting this to
work, especially considering there were a variety of other errors that meant ISVis was not
going to compile anyway.
Another of my initial tasks was to create a CVS repository to store all the changes that
were made to ISVis. After a couple of administrative hiccups this was created and
available for use. I also created an access policy describing how to use the CVS
repository and created a template to record what changes had been made when someone
checked in changes.
Initially I started editing the ISVis code by using SSH to log in to lennon and then editing
the source files with vi and then using the CC compiler or the makefile when it had been
created. However, I soon realized that this was not particularly productive. I then
switched to using Eclipse with the C++ plug-in on my personal Linux machine. The
advantage here was that CVS, file editing and compiling were all combined into a single
application and as a result my productivity increased noticeably. A particular time when
Eclipse proved very useful was when I merged my changes back into the main branch of
CVS. The Synchronize view in Eclipse allows a developer to view the two different
versions of a file and to automatically most of the changes. The few changes where
manual intervention was required were clear to see in the display and did not take much
time.
There were a large amount of changes required to remove all instances of Rogue Wave,
at one point there was over 2,500 errors due to replacing the RWCString class and not
updating the rest of the code to reflect this. As the Rogue Wave collection classes were
replaced the number of errors dropped dramatically, and once this was complete and had
been checked into the main branch the number of errors had dropped to around 100.
These were related to the persistence code. Changing this code was proving to be a
challenge and it was decided to create method stubs so that ISVis could be compiled
without the persistence functionality. It was at this point that a small issue arose, as I
mentioned earlier I had been using Eclipse to compile the code on a Linux machine, and
there were no errors left, however, it seemed that there were still errors when compiling
using the Sun CC compiler. These were duly fixed and ISVis compiled using the Sun CC
compiler, but would not link. The reason for this was that the C++ libraries on lennon
were out of date and needed updating. After this had been done we finally had an
executable. Unfortunately, when we tried to run ISVis it crashed on startup. I spent
some time debugging and it seems to be error in allocating colors from X Windows
13
global palette. As I am not very familiar with X Windows and Motif I was unsure of how
the problem could be fixed.
Regarding the current state of persistence, there are two options: either complete the
changes using standard C++ or employ a library that provides serialization functionality.
The first option would be more complex and harder to implement, whilst the second
option would mean that there was a dependency on a third party library which was one of
the reasons for removing Rogue Wave in the first place.
Motif
In order to upgrade and make the necessary adjustments to the Motif code, I first had to
take time for research. I had to refresh my skills, since it has been about 6 years that I
have written with Motif. I also had to research the differences between the current
version of Motif, 2.1, and the existing 1.2 version of the Motif code in ISVis. Then I was
able to make an analysis of what needed to be done to upgrade the Motif code and make a
time estimate on the task. I created a Motif proposal that contained all of my findings and
submitted it for approval.
When we were finally able to compile individual source files, I had a better idea on what
needed to done. There were twenty-nine critical compile errors in the following files and
three warnings:
 Scenario View
 Mural
 IO Shell
 View Manager
 Xapp
It was first decided that only the critical compile errors would be addressed, so that we
could get ISVis up and running, but I was able to not only fix the critical errors, but the
warnings also. At the present time, all of the compile errors have been fixed and Motif
has been upgraded to version 2.1. The first phase of this project was to get ISVis up and
running and we have almost reached that point. We have all the compile errors addressed
and most of all the warnings. We didn’t actually get the program to run, but I believe that
we are right on the cusp of it, so that would be the next logical step. Get ISVis to run on
Solaris and then test it with a subject program and make sure that it functions correctly.
Doing this may result in more modifications needed to for the Motif code, but I really
don’t anticipate that happening.
After ISVis is running and behaving as expected, there is the next phase of this project,
which is to get ISVis platform independent. Motif is a graphical user interface toolkit that
was designed to run on X Windows systems. In order to make ISVis more portable, it
might make more sense to use a tool kit that was designed to be platform independent,
like the Java toolkit. The option of using Java used to not be as desirable as using others
because of timing issues, but it has since proven to be much more stable, reliable and
faster. I would recommend doing some investigation and think about changing toolkits.
14
MakeFile
The makefile had to be changed a lot in order for it to be used in our project. The one that
was in the original version of ISVis created to many problems, so instead of just editing
the original makefile, I decided to create a new one. I spent time in the beginning of this
project, researching the format and structure of the Makefile, and edited it during the
course of this project. All total, I spent thirty-eight hours creating, editing and
maintaining the Makefile. I first had to modify it so that we could compile each source
file individually. The header files that were included in the source files were included
incorrectly, so each one of those had to be corrected. After making a lot of changes to the
Makefile, I was able to get each source file to compile using the cc compiler. I put all of
the compiler errors and warning in text files and sent that information from each file to
the group. This allowed all of us to start modifying our sections of the code in order to
get a clean compile. Along the way I also had to edit the Makefile to find various items
that have changed locations in the last ten years, which would make the existing paths
incorrect and not work. I also had to remove files that were no longer needed and remove
and add different compiler flags, in order to get the files to compile. After we all finished
our modifications to the code and Peter checked in his code and stubbed out his
remaining methods, we got a compile of the entire program. I also had to make
modifications to the makefile in order to compile ISVis as a whole.
From this point forward, it would depend on the direction of ISVis as to what will need to
be done to the makefile in the future. If someone proceeds to the next phase, which is to
make ISVis portable to different platforms, then a makefile will not be needed for a
windows installation. If the program is to be run on a Linux or UNIX machine, the
makefile might need to be edited to accommodate this. I have included two links in the
References section that might be helpful to the person that will be handling this from this
point forward.
Solaris
To research the system function call and library API call used in the ISVis source code. If
they have compiled errors, make them be compiled. But actually, there are no compile
errors of the system function or library API call, so I just present the methods by the form
as shown below if these function calls got the compiled errors.
When dealing with the system () function calls of library API, we found out that there are
three scripts used and they are stored in the bin directory of ISVis package. I spent a lot
of time studying what they are and get involved with the sbrowser and sbdump which are
provided by the Sun SPARCworks technology. But SPARCworks is replaced by Sun
Studio several years ago and is not supported any more. So I thought they are not
available at first. But actually, they are still supported in the lennon machine, which is a
server we use for this project in Georgia Tech. So finally I do tiny changes in the two
15
scripts for the path of current sbdump and change the directory name of .sb files which
are generated by the sbrowser as described below.
(1) In the test program, Polka which is in
\isvis.source.solaris\morale\isvis\tutorial\Polka
If you use the Makefile to compile and generate the .bd files, you need to
replace
INCLUDES = -I/usr/openwin/include -I/usr/dt/include \
-I/opt/SUNWspro/SC3.0.1/include/CC
with
INCLUDES = -I/usr/openwin/include -I/usr/dt/include \
-I/usr/local/opt/SUNWspro6.2/WS6U2/include/CC
(2) Original sbdump path:
system "/opt/SUNWspro/SW3.0.1/bin/sbdump $file > /tmp/sbtemp";
Current sbdump path:
system "/usr/local/opt/SUNWspro6.2/WS6U2/bin/sbdump $file >
/tmp/sbtemp";
So I replace the every original path of sbdump with current path.
(3) Original directory and path of .bd files generated by sbrowser:
.sb/NewRoot/$exec_name.*.bd
.sb/Refd/$bd_filename
Current directory and path of .bd files generated by sbrowser:
SunWS_cache/sb_NewRoot/$exec_name.*.bd
SunWS_cache/sb_Refd/$bd_filename
So I replace all the original paths of .bd files with current path.
The following diagram is the relationship between the scripts and ISVis
16
4. Conclusion
Michele
Looking back and reviewing the process of our project this semester, there were things
that ran smoothly, tools and processes that we used that was very helpful and there were
things that didn’t go quite as well as we planned. Some of the things that we used that I
found to be helpful were:




Time log
Bibliography
Website
CVS
I felt that having a web site was a very good idea. It allowed us to have one place to store
all of our data and we were all able to access the data. It allowed us to share information
that we found during the course of our assigned tasks and present it to the group. We had
a location to post our meeting time and place, contact information for everyone in the
group, a place to put all of our papers that we located each week, a place to post our time
logs, and a place to put all the information regarding the progress of our work.
17
I think that looking up papers each week relating to our project was very helpful. Some of
the papers had some really good ideas on how to upgrade software and were relevant to
what we were trying to accomplish. Some of the papers had absolutely no bearing on
what we were doing, but most did have interesting ideas on how to maintain and upgrade
software in general. I think that we all agreed that what we were trying to accomplish has
not been attempted or maybe it hasn’t been published in a paper. I do think it would be a
good idea for those that will continue with this project to continue to look up relevant
papers or articles, because they might stumble upon some helpful information that could
be applied to this project.
The time log turned out to be more helpful to me at the end of the project than during the
course of this project. When it came time to gather my data from this project in order to
write this paper and add my results to the report, the time log became invaluable. I was
able to go back and look at it to see exactly how much time I spent on this project, how
much time I spent on each category, and what I did for each category. I would strongly
suggest to anyone that is spending time on any project, to use some kind of time log to
document how they spent their time during the process. I think it would be extremely
helpful if you are involved in a project when there multiple people involved at different
stages, to utilize a time log. The time logs could serve as a journal, where new people
could become more familiar with the project and easily find out the status.
Having the CVS repository for our source code was also a very good idea. I have worked
on other projects where we didn’t have a repository and relied on sending source files
back in forth in email and it was disastrous. The margin for error is too great, with work
being lost or changes being clobbered. Having all the source code in one place and
having people check code in and out is much safer, especially if there are multiple people
working in the same source code.
With all these processes and items that were created that worked well, there was also
things that didn’t work so well. Time estimations were not always correct,
communication seemed to not be as expedient as desired and distribution of tasks was
uneven. Of course all these things seemed to creep up during the course of this project
and probably most of them could not have been predicted at the beginning, but these are
all things that we would probably look out for and try and prevent in the future. Some of
the issues that I felt occurred during this project are:




Uneven distribution of tasks.
Time estimations were incorrect.
Group communication on status of assigned tasks.
Learning curve on ISVis.
As I stated earlier, the assignment of tasks for each of us turned out to be uneven. Some
tasks were much more complex than first thought and took much longer time than
estimated. Of course, there were other tasks that were not much work and took less time
than what was estimated. I really don’t think that these things can be predicted or
prevented from becoming an issue during the course of a project. You cannot really know
18
how difficult changing outdated source code can be, until you get in there and start
working with it. There are too many variables involved. For example, you might fix
something that breaks something else or has a domino effect on code that is dependent on
that code you edited. In our case, the persistence turned out to be much more complex
than Peter had anticipated. After initially investigating the code and making his analysis
and time estimations, he felt that the best course of action was to get rid of the Rogue
Wave dependency and rewrite it. After he got involved in making the adjustments, he
found that it was a lot more complicated than he originally thought. The Makefile also
turned out to be a complex issue; one that none of us had considered and it turned out to
play a critical role in getting the program to compile. In my opinion, when these kind of
issues crop up during a project, the team just needs to be flexible and rearrange the
distribution of assignments to accommodate them.
I also think that the communication for our group could have been better. We all
depended on each other for the success of our project, because we each held a vital piece.
I think it would have been nicer if the communication would have been more open
outside of our weekly meetings. The time outside of our meetings is the time that the
actual work is being done. I think that it would have been helpful if we would have
chosen an instant messenger program, created and exchanged login names, and used that
to contact each other. I am sure that there were issues and questions that we could have
all benefited by having the others to consult with outside of our designated meeting
times.
I also felt that we all had a very large learning curve with how ISVis worked. I think that
we could have possibly approached this a little differently and maybe all gained a better
understanding more quickly. I think that at the very beginning, we should have all taken
the program and each one produced a different diagram to illustrate how it worked. Each
person would be looking at the program in a slightly different way and we wouldn’t all be
trying to understand it as a whole. Then we could get back together and discuss the
diagrams and our findings. This would save time and we would all have had a better
understanding of how it worked. Looking back on it now, it would have been nice to have
had a high level diagram on how the classes interacted with each other and the purpose of
each class file. So, in the future, I would try to organize the analysis of the code by
dividing it up between those involved and have them create a different UML diagram.
All in all, I felt that we were successful in our endeavors this semester. Although there
were a lot of issues that arose, I believe that we dealt with them as they came up and we
all learned from them. ISVis is a large program and there was a learning curve for all of
us and not only with ISVis, but the other factors like Solaris, the Makefile and C++. All
in all, we did manage to get a clean compile of ISVis.
Peter
Overall, this project has been a good learning experience when dealing with updating old
projects. This is always a difficult area as was demonstrated in some of paper that we
had read.
19
As with all projects there are some positives and some negatives. First the positives.
Significant progress was made towards updating ISVis, there is now a version of ISVis
that will compile, whilst there are still issues with the persistence side and actually
running ISVis a large portion of the changes required have been made. The fact that
ISVis will compile on both SunOS and Linux is a large step towards portability. A more
significant step would be to compile on Windows, but that would require more effort.
Furthermore, reading papers that were directly or indirectly related to this project help
everyone get a better feel for ways to proceed with a project like this. Also, whilst I have
used Eclipse for several Java projects previously I have found there to much more useful
functionality that helped to improve my productivity and I shall consider using Eclipse
again for future C++ projects. CVS was also a very valuable asset for this project as is
some form of source control for any project particularly of there are several developers
contributing as it eases the combining of different code branches greatly. Another vital
feature is the logging which allows the changes that are made to be captured clearly and
was useful for me in finding exactly how many changes were made.
As for the negatives, the main issue for me is that I was not able to complete the changes
to enable persistence to work. There are several reasons for this, but it is mainly because
I underestimated the amount of work required. This was in part due to the lack of
documentation for ISVis which meant I did not realize how complex it actually was, and
as ISVis could not be run it was difficult to see understand all the functionality by just
viewing the code. But this is something I will bear in mind when estimating the effort
required for future projects.
Other negatives are something of a lack of structure to the project. Initially, there was a
project plan created, but it was not really referred later on. Possibly more emphasis on
keeping to the plan could have addressed issues of slippage earlier and corrective action
could have been taken.
In conclusion, ISVis is a large and complex program that lacked documentation that
made it difficult to understand the functionality of the program . But a significant amount
of progress was made towards updating the code to something that would work.
Eventually a version that would compile cleanly was produced, and hopefully it should
not take much more effort to have a fully functioning version of ISVis again.
Phil
As a whole, this project was very successful compared against other attempts in the past
to get the code compiled and running. However, I do think it could have been more
successful. While it is always necessary to be prepared on any project for unanticipated
problems, you can’t always predict what they will be and when they will occur. The most
important area to be consistent and thorough in is with intra team communication. This
was a big problem on the project in that many times, several days would elapse before
other team members would provide responses to emails. It was often the case during that
time to for little or no forward progress to be made do to a lack of a timely response to an
email. Also, I think it is important to have all team members’ work on each part of the
project to some degree. This makes it easier for someone to step in and contribute if one
area is lagging behind or there are problems trying to understand the current area. I do
20
think that each team member needs to lead up a certain section, but they also should be
familiar with what others are doing.
For our project, I would like to have seen more interaction between the team members. I
felt that after we left our meetings, I really had no clue about what anyone was doing
until it came to our meeting the next week. It would have been much more beneficial to
all if we had kept closer contact outside of the meetings. I was frustrated at times with no
replies to emails or if I was waiting on code to be checked in so I could proceed with my
next task. In hindsight, it would have been helpful for everyone to send out a status report
midway between our weekly team meetings, in order to keep everyone better informed of
their progress.
Creating a project plan is a necessary task since, once created, it gives everyone a
constant reminder how much time you have left to reach your goal and how much work
you have to do in order to reach that goal. It helps you to plan and organize your time
more efficiently because you have a constant reminder of your deadlines. It is very easy
to get a little lackadaisical and caught up in the details if you don’t have a realistic visual
reminder of deadlines and where you are in regards to those deadlines. I think that we
started out on the right track with the project plan, but then dropped the ball and didn’t
use it anymore. Looking back on it now, we should have found some tool to create it with
that was accessible to everyone. It was posted on the website, but I think that we should
have revisited it at every meeting and kept it up to date with the progress reports.
I also think that we should have been more insistent on our deadlines for each task in our
project. I know that some tasks turned out more complex than others, but if we tried to
stay with our projected time estimates and deadlines, that we might have been a little
quicker in getting them done. If we tried to stay on target, then we might have
collaborated more and helped each other out more. Sometimes it is better to be stricter
with target dates, because it makes the team members strive a little harder to get the job
done.
There was a very large learning curve from the beginning with this project. ISVis is a
large and complex program and there was not a lot of documentation available on it. The
source code was not formatted well and there were virtually no comments in the code to
indicate what the methods and classes were for. I think that it would have been more
beneficial to us to have spent more time up front becoming familiar with this program. In
searching to find information on sbdump, I stumbled upon a website that was created by a
previous class that attempted to achieve the same goal with ISVis as we. In the end, they
were not successful, but the website had some fairly informative diagrams and
information on what each class did. This information would have been very beneficial to
have up front at the beginning of this project.
There was also a fair amount of time spent refreshing other skills, such as Motif, Solaris,
Makefile syntax, etc. However, in retrospect, I do not see anyway to speed up or avoid
this need. About all that can be done is to plan accordingly for it in the project timeline.
21
In conclusion, I believe the forward progress we made in meeting our goals on this
project was significant. We succeeded in correcting all the C++, OS, and Motif compile
errors as well as make significant progress in removing the Rogue Wave dependency. We
finished with a clean compile of ISVis on Solaris and have provided the follow-up team
with a sound and stable base with which to build on. Because of this, I believe that the
upcoming team will have a high probability of success in getting ISVis back to its
original, run able state and can then proceed with the follow on task of making it platform
independent.
Barrie
In order to fulfill the project, I have had learned a lot of knowledge of Solaris operation
system. First, I know that I can get much information from the man command not only
that I used have. I misunderstand the difference between system call and system() in
library API call. Actually, system calls are functions that a programmer can call to
perform the services of the operating system. And system() is when you use it, the
content is the same as using the command line to run a command such as system(“mkdir
newDirectoy”). Additionally, I learned using script files to run some program except the
main program. I learned something about shell script and perl script. I don’t get much
about this for the project however I think I will learn it by myself later. I also learned
more about the structure about the operation system, like opt which means optional, to
store some optional packages in this directory and tmp, which means temporary, basically
to store some temporary files in this directory, we know there is also a temp directory in
Windows operation system. Another directory is bin, which means binary, is used to store
the executable binary files.
REFERENCES
1. Dig D, Johnson R. How do API’s Evolve. Journal of Software Maintenance and
Evolution: Research and Practice
2. Bastide G. A Refactoring-based Tool for Software Component Adaptation.
Proceedings of the Conference on Software Maintenance and Reengineering
3. Pazel D, Varma P, Paradkar A, Tibbitts B, Anand A, Philippe C. A Framework
and Tool for Porting Assessment and Remediation. Proceedings of the 20th IEEE
International Conference on Software Maintenance(ICSM'04)
4. Rahgozar M, Oroumchian F. An effective strategy for legacy systems evolution.
Journal of Software Maintenance and Evolution: Research and Practice
5. Mealy E, Strooper P. Evaluating Software Refactoring Tool Support. Proceedings
of the 2006 Australian Software Engineering Conference (ASWEC'06)
6. Wang S, Schach S, Heller G. A Case Study in Repeated Maintenance. Journal of
Software Maintenance and Evolution: Research and Practice
7. Mens T, Buckley J, Zenger M, Rashid. Towards a Taxonomy of Software
Evolution.
22
8. Yang Y, Munro M, Kwon Y. An improved method of selecting regression tests
for C++ programs. Journal of Software Maintenance and Evolution: Research
and Practice
9. Parnas D. Separation of concerns for software evolution. IEEE 1994
10. Mens T and Wermelinger M. Separation of concerns for software evolution.
Journal of Software Maintenance and Evolution: Research and Practice
11. Carrier S, Woods S, Kazman R. Software Architecture Transformation.
12. Ahrens J and Pryres N. "Transition to a Legacy and Reuse based Software Life
Cycle". IEEE Computer October 1995
13. Hongji Yang, Xiaodong Liu, Hussein Zedan. Abstraction: a key notion for reverse
engineering in a system reengineering approach. Journal of Software
Maintenance: Research and Practice, Volume 12, Issue 4, Date: July/August
2000, Pages: 197-228
14. Matthew Harrison, Gwendolyn Walton. Identifying High Maintenance Legacy
Software. Journal of Software Maintenance: Research and Practice, Volume 14,
Issue 6, Date: January 2003, Pages: 429-446
15. Jianjun Zhao, Hongji Yang, Liming Xiang, Baowen Xu. Change impact analysis
to support architectural evolution. Journal of Software Maintenance: Research
and Practice, Volume 14, Issue 5, October 2002
16. West R. Improving the Maintainability of Software. Journal of Software
Maintenance: Research and Practice, Volume 8, Issue 8, Date: September 1996,
Pages: 345-356
17. Advani, Deepak; Hassoun, Youssef; Counsell, Steve. Understanding the
complexity of refactoring in software systems: a tool-based approach.
International Journal of General Systems, Jun2006, Vol. 35 Issue 3, p329-346,
18p
18. Sneed H. Measuring Reusability of Legacy Software Systems. Software Process:
Improvement and Practice Volume 5, Issue 2-3, Date: June - September
2000,Pages: 183-195
19. Scacchi W. Understanding software process redesign using modeling, analysis
and simulation. Software Process: Improvement and Practice Volume 5, Issue 23, Date: June - September 2000,Pages: 183-195
20. Olsem M. An incremental approach to software systems re-engineering. Journal
of Software Maintenance:Research and Practice, Volume 10, Issue 3, Pages 181202
21. Sam Ramanujan, Richard W. Scamell and Jaymeen R. Shah. An Experimental
investigation of the impact of individual, program, and organizational
charactersitics on software. The Journal of Systems and Software 54.2 (Oct 15,
2001): p137(1)
22. Alessandro Bianchi, Danilo Caivano, Vittorio Marengo, Giuseppe Visaggio.
Iterative Reengineering of Legacy Functions. IEEE International Conference on
Software Maintenance, 2001 (7-9 Nov 2001), pp 632-641
23. Ned Chapin, Joanne E. Hale, Khaled Md. Khan, Juan F. Ramil, Wui-Gee Tan.
Types of software evolution and software maintenance. Journal of Software
Maintenance and Evolution: Research and Practice Volume 13, Issue 1,
Date: January/February 2001, Pages: 3-30
23
24. Webster, Oliveira, Anquetil. A risk taxonomy proposal for software maintenance.
Proceedings of the 21st IEEE International Conference on Software Maintenance
(ICSM'05) - Volume 00 Pages 453-461
25. Kim Mensa, Andy Kellensb, Frédéric Pluquetc, Roel Wuytsc. Tanaka T., Hakuta
M., Iwata N., Ohminami M. Co-evolving code and design with intensional views.
Computer Languages, Systems & Structures Volume 32, Issues 2-3 , July-October
2006, Pages 140-156 Smalltalk
26. Tanaka T., Hakuta M., Iwata N., Ohminami M. Approaches to making software
porting more productive. Proceedings of the 12th TRON Project International
Symposium, 1995, (28 Nov-2 Dec 1995), pp 73 - 85
27. Jintae Lee, Claude Stricker. Function-based Process Analysis: A Method for
Analyzing and Re-engineering Processes. Knowledge and Process Management
Volume 4, Issue 2, Date: June 1997, Pages: 126-138
28. Ackers, Baxter, Mehlich, Ellis, Luecke. Automated Restructuring of ComponentBased Software. CrossTalk-The Journal of Defense Software Engineering, May
2005 issue
29. Suenobu, Honma, Tsuruta, Kasahara, Masuda, Uchara. Stepwise approach for
introducing object-oriented technique at software maintenance stages. Systems,
Man, and Cybernetics, 1999. IEEE SMC '99 Conference Proceedings. 1999 IEEE
International Conference on Publication; Date: 12-15 Oct. 1999; Volume: 5;
Number of Pages: 6 vol. (1179+1075+1106+1124+1140+1078)
30. Verhoef C. Towards automated modification of legacy assets. Annals of Software
Engineering 9 (2000) pp 315-336
31. Wilkening, D.E.; Littlejohn, K. Legacy software reengineering technology.
Digital Avionics Systems Conference, 1996., 15th AIAA/IEEE 27-31 Oct. 1996
Page(s):25 - 30 Digital Object Identifier 10.1109/DASC.1996.559129
32. Bergey, Smith, Weiderman. DoD Legacy System Migration Guidelines. Carnegie
Mellon Software Engineering Institute - Technical Report CMU/SEI-99-TN-013
33. Mens, Tourwe', Munoz. Beyond the Refactoring Browser: Advanced Tool
Support for Software Refactoring. Proceedings of the Sixth International
Workshop on Principles of Software Evolution (IWPSE'03) 0-7695-1903-2/02
$17.00 © 2002 IEEE
34. Sneed, H. Encapsulation of legacy software: A technique for reusing legacy
software components. Annals of Software Engineering 9 (2000) pp293-313
35. Song, W.W. Integration issues in information system reengineering. Computer
Software and Applications Conference, 1996. COMPSAC '96., Proceedings of
20th International 21-23 Aug. 1996 Page(s):328 - 335 Digital Object Identifier
10.1109/CMPSAC.1996.544586
36. Rosenberg. Software Re-engineering. System Reliability and Safety Office,
Goddard Spaceflight Center, NASA
37. Tahvildari, L.; Kontogiannis, K.; Mylopoulos, J. Requirements-driven software
re-engineering framework. Reverse Engineering, 2001. Proceedings. Eighth
Working Conference on 2-5 Oct. 2001 Page(s):71 - 80
38. Gordon, D., Werner, L. An Empirical Study of Software Porting Obstacles. June
12 1999, 9 pages
24
39. Ron Morrison, Dharini Balasubramaniam, Mark Greenwood, Graham Kirby, Ken
Mayes, Dave Munro, Brian Warboys. A compliant persistent architecture.
Software: Practice and Experience Volume 30, Issue 4, Date: 10 April 2000,
Pages: 363-386
40. David Eichman. Factors in Reuse and Reengineering of Legacy Software.
Repository Based Software Engineering Program Research Institute for
Computing and Information Systems University of Houston – Clear Lake
41. Chu, W. C., Lu, C. W., Shiu C. P., He, X. Pattern-based software reengineering: a
case study. Journal of software maintenance: research and practice, Volume 12,
Issue 2, March/April 2000, pp 121-14
42. Alan Dearle, David Hulse. Operating system support for persistent systems: past,
present and future. Software: Practice and Experience Volume 30, Issue 4,
Date: 10 April 2000, Pages: 295-324
43. Fanta and Rajlich. Reengineering object oriented code. Proceedings of the
International Conference on Software Maintenance, 1998
44. Sergio Cozzetti B. de Souza, Nicolas Anquetil, Kathia M de Oliveira. A study of
the documentation essential to software maintenance. ACM Special Interest
Group for Design of Communication archive Proceedings of the 23rd annual
international conference on Design of communication: documenting & designing
for pervasive information, Coventry, United Kingdom, SESSION: Document
authoring, production and management, Pages: 68 - 75, Year of Publication:
2005, ISBN:1-59593-175-9
45. Terekhov, A. Automating Language Conversion: A case study. IEEE
International conference on software maintenance, 2001
46. Rainer Koschke. Software visualization in software maintenance, reverse
engineering, and re-engineering: a research survey. Journal of Software
Maintenance and Evolution: Research and Practice Volume 15, Issue 2,
Date: March/April 2003, Pages: 87-109
47. Buss, Henshaw. A software reverse engineering experience. IBM Centre for
Advanced Studies Conference archive Proceedings of the 1991 conference of the
Centre for Advanced Studies on Collaborative research table of contents,
Toronto, Ontario, Canada SESSION: Design technologies table of contents Pages:
55 - 73, Year of Publication: 1991
48. Douglas Gregor, Jaakko Järvi, Jeremy Siek, Bjarne Stroustrup, Gabriel Dos Reis,
Andrew Lumsdaine. Concepts: Linguistic Support for Generic Programming in
C++. October 2006 ACM SIGPLAN Notices , Proceedings of the 21st annual
ACM SIGPLAN conference on Object-oriented programming languages,
systems, and applications OOPSLA '06, Volume 41 Issue 10
49. Ernst Fricke, Armin P. Schulz. Design for changeability (DfC): Principles to
enable changes in systems throughout their entire lifecycle. Systems Engineering
Volume 8, Issue 4, Date: 2005
50. Tommi Mikkonen, Peeter Pruuden. Practical perspectives on software
architectures, high-level design, and evolution. International Conference on
Software Engineering archive, Proceedings of the 4th International Workshop on
Principles of Software Evolution table of contents, Vienna, Austria SESSION:
25
Session 6A: Architectures table of contents, Pages: 122 - 125, Year of
Publication: 2001, ISBN:1-58113-508-4
51. Keith Bennett, Vaclav Rajlich. Software Maintenance and Evolution: A
Roadmap. International Conference on Software Engineering archive,
Proceedings of the Conference on The Future of Software Engineering table of
contents, Limerick, Ireland, Pages: 73 - 87 Year of Publication: 2000, ISBN:158113-253-0
52. Christian Del Rosso. Continuous evolution through software architecture
evaluation: a case study. Journal of Software Maintenance and Evolution:
Research and Practice Volume 18, Issue 5, Date: September/October 2006,
Pages: 351-383
APPENDIX A
David R. Tribble. Incompatibilities between ISO C and ISO C, Aug 5, 2001. Online.
Internet. David R Tribble. http://david.tribble.com/text/cdiffs.htm#C99-vs-CPP98
Items
Array parameter qualifiers
1
Old: allowed type qualifiers (the cv-qualifiers const and volatile, and restrict) to be
included within the first set of brackets of an array declarator. The qualifier modifies the type of the
array parameter itself. In both declarations, parameter str is a const pointer to an int object.
extern void
extern void
foo(int str[const]);
foo(int *const str);
Also allowed the static specifier to be placed within the brackets of an array declaration immediately
preceding the expression specifying the size of the array. The presence of such a specifer indicates that
the array is composed of at least the number of contiguous elements indicated by the size expression.
void baz(char s[static 10])
{
// s[0] thru s[9] exist and are contiguous
...
}
New: None of these new syntactic features are recognized.
Boolean type 2
Old: Supports the _Bool keyword. It also provides a standard <stdbool.h> header that contains
definitions for the following macros:
bool
Same as _Bool
false
Equal to (_Bool)0
true
Equal to (_Bool)1
New: provides bool, false, and true as reserved keywords and implements bool as a true built-in
boolean type.
26
Character literals
4
Old: character literals such as 'a' have type int, and thus sizeof('a') is equal to
sizeof(int).
New: character literals have type char, and thus sizeof('a') is equal to sizeof(char).
clog identifier 5
OLD: declares clog() in <math.h> as the complex natural logarithm function.
NEW: declares std::clog in <iostream> as the name of the standard error logging output stream
(analogous to the stderr stream). This name is placed into the global namespace if the <math.h>
header is included, and refers to the logarithm function. If <math.h> defines clog as a preprocessor
macro name, it can cause problems with other C++ code.
// C++ code
#include <iostream>
using std::clog;
#include <math.h>
// Possible conflict
void foo(void)
{
clog << clog(2.718281828) << endl;
// Possible conflict
}
Comma operator results 6
OLD: The comma operator always results in an r-value even if its right operand is an l-value.
NEW: C++ the comma operator will result in an l-value if its right operand is an l-value. This means
that certain expressions are valid in C++ but not in C:
int
int
i;
j;
(i, j) = 1;
// Valid C++, invalid C
Complex floating-point type 7
OLD: Has built-in complex and imaginary floating point types, which are declared using the
_Complex and _Imaginary keywords.
There are exactly three complex types and three imaginary types:
_Complex float
_Complex double
_Complex long double
_Imaginary long double
_Imaginary double
_Imaginary long double
27
There is a standard <complex.h> header that contains definitions of complex floating point types,
macros, and constants. In particular, this header defines the following macros:
complex
Same as _Complex
imaginary
Same as _Imaginary
I
i (the complex identity)
Code that does not include this header is free to use these words as identifiers and macro names.
Implicit widening conversions between the complex and imaginary types are provided, which parallel
the implicit widening conversions between the non-complex floating point types.
#include <complex.h>
complex double square_d(complex double a)
{
return (a * a);
}
complex float square_f(complex float a)
{
complex double d = a;
// Implicit conversion
return square_d(a);
// Implicit conversion
}
NEW: provides a template class named complex, declared in the <complex> standard header file.
This type is incompatible with the C99 complex types.
// C++ code
#include <complex>
complex<float> square(complex<float> a)
{
return (a * a);
}
complex<int> square(complex<int> a)
{
return (a * a);
}
Compound literals 8
OLD: allows literals having types other than primitive types (e.g., user-defined structure or array types)
to be specified in constant expressions; these are called compound literals. For example:
struct info
{
char
name[8+1];
int
type;
};
extern void
extern void
add(struct info s);
move(float coord[2]);
28
void predef(void)
{
add((struct info){ "e", 0 });
move((float[2]){ +0.5, -2.7 });
}
// A struct literal
// An array literal
NEW: does not support this feature.
C++ does provides a similar capability through the use of non-default class constructors, but which is
not quite as flexible as the C feature:
void predef2()
{
add(info("e", 0));
// Call constructor info::info()
const linkage 9
OLD: specifies that a variable declared with a const qualifier is not a modifiable object. In all other
regards, though, it is treated the same as any other variable. Specifically, if a const object with file
scope is not explicitly declared static, its name has external linkage and is visible to other source
modules.
const int
i = 1;
// External linkage
extern const int
static const int
j = 2;
k = 3;
// 'extern' optional
// 'static' required
NEW: specifies that a const object with file scope has internal linkage by default, meaning that the
object's name is not visible outside the source file in which it is declared. A const object must be
declared with an explicit extern specifier in order to be visible to other source modules.
const int
i = 1;
// Internal linkage
extern const int
static const int
j = 2;
k = 3;
// 'extern' required
// 'static' optional
Designated initializers 10
OLD: introduces the feature of designated initializers, which allows specific members of structures,
unions, or arrays to be initialized explicitly by name or subscript. For example:
struct info
{
char
name[8+1];
int
sz;
int
typ;
};
struct info arr[] =
{
[0] = { .sz = 20, .name = "abc" },
[9] = { .sz = -1, .name = "" }
};
Unspecified members are default-initialized.
29
NEW: does not support this feature.
Duplicate typedefs 11
OLD: does not allow a given typedef to appear more than once in the same scope.
NEW: handles typedefs and type names differently and allows redundant occurrences of a given
typedef within the same scope.
Thus the following code is valid in C++
typedef int
typedef int
MyInt;
MyInt;
Dynamic sizeof evaluation 12
OLD: supports variable-length arrays (VLAs), the sizeof operator does not necessarily evaluate to a
constant (compile-time) value. Any expression that involves applying the sizeof operator to a VLA
operand must be evaluated at runtime (any other use of sizeof can be evaluated at compile time). For
example:
size_t dsize(int sz)
{
float
arr[sz];
// VLA, dynamically allocated
if (sz <= 0)
return sizeof(sz);
else
return sizeof(arr);
// Evaluated at compile time
// Evaluated at runtime
}
NEW: does not support VLAs
Empty parameter lists 13
OLD: distinguishes between a function declared with an empty parameter list and a function declared
with a parameter list consisting of only void. The former is an unprototyped function taking an
unspecified number of arguments, while the latter is a prototyped function taking no arguments.
extern int
extern int
foo();
bar(void);
void baz()
{
foo(0);
foo(1, 2);
bar();
bar(1);
// Unspecified parameters
// No parameters
// invalid C++
// invalid C++
// Okay in both
// Error in both
}
NEW: makes no distinction between the two declarations and considers them both to mean a function
taking no arguments.
// C++ code
extern int
xyz();
extern int
xyz(void);
// Same as 'xyz()' in C++,
30
Empty preprocessor function macro arguments 14
OLD: allows preprocessor function macros to be specified with empty (missing) arguments.
#define ADD3(a,b,c)
ADD3(1, 2, 3)
ADD3(1, 2, )
ADD3(1, , 3)
ADD3(1,,)
ADD3(,,)
=>
=>
=>
=>
=>
(+ a + b + c + 0)
(+
(+
(+
(+
(+
1
1
1
1
+
+
+
+
+
+
2
2
+
+
+
+ 3 + 0)
+ + 0)
3 + 0)
+ 0)
0)
NEW: does not support empty preprocessor function macros arguments.
Enumeration constants 15
OLD: Enumeration constants are essentially just named constants of type signed int. As such, they
are constrained to having an initialization value that falls within the range [INT_MIN,INT_MAX]. This
also means that for any given enumeration constant RED, the values of sizeof(RED) and
sizeof(int) are always the same.
NEW: enumeration constants have the same type as their enumeration type, which means that they have
the same size and alignment as their underlying integer type. This means that the values of
sizeof(RED) and sizeof(int) are not necessarily the same for any given enumeration constant
RED. Enumeration constants also have a wider range of possible underlying types in C++: signed
int, unsigned int, signed long, and unsigned long. As such, they also have a wider range
of valid initialization values.
Enumeration declarations with trailing comma 16
OLD: allows a trailing comma to follow the last enumeration constant initializer within an enumeration
type declaration, similar to structure member initialization lists. For example:
enum Color { RED = 0, GREEN, BLUE, };
NEW: does not allow this.
Enumeration types 17
OLD: specifies that each enumerated type is a unique type, distinct from all other enumerated types
within the same program. The implementation is free to use a different underlying primitive integer type
for each enumerated type. This means that sizeof(enum A) and sizeof(enum B) are not
necessarily the same. This also means, given that RED is an enumeration constant of type enum Color,
that sizeof(RED) and sizeof(enum Color) are not necessarily the same (since all enumeration
constants are of type signed int).
All enumeration constants, though, convert to values of type signed int when they appear in
expressions. Since enumeration constants cannot portably be wider than int, it might appear that int
is the widest enumeration type; however, implementations are free to support wider enumeration integer
types. Such extended types may be different than the types used by a C++ compiler, however.
Objects of enumeration types may be assigned integer values without the need for a explicit cast. For
31
example:
enum Color { RED, BLUE, GREEN };
int
enum Color
c = RED;
col = 1;
// Cast not needed
// Cast not needed
NEW: also specifies that all enumerated types are unique and distinct types, but it goes to enforce this.
In particular, a function name can be overloaded to take an argument of different enumerated types.
While objects of enumerated types implicitly convert to integer values, integer values require an explicit
cast to be converted into enumerated types. Implicitly converted enumeration values are converted to
their underlying integer type, which is not necessarily signed int. For example:
// C++ code
enum Color { ... };
enum Color setColor(int h)
{
enum Color c;
c = h;
return c;
// Error, no implicit conversion
}
int hue(enum Color c)
{
return (c + 128);
// Implicit conversion,
// but might not be signed int
}
Since a C++ enumeration constant has the same type and size as its enumeration type, this means, given
that RED is an enumeration constant of type enum Color, that the values of sizeof(RED) and
sizeof(enum Color) are exactly the same.
Flexible array members (FAMs) 18
OLD: This is also known as the struct hack. This specifies a conforming way to declare a structure
containing a set of fixed-sized members followed by a flexible array member that can hold an
unspecified number of elements. Such a structure is typically allocated by calling malloc(), passing it
the number of bytes beyond the fixed portion of the structure to add to the allocation size. For example:
struct Hack
{
int
count;
int
fam[];
};
// Fixed member(s)
// Flexible array member
struct Hack * vmake(int sz)
{
struct Hack * p;
p = malloc(sizeof(struct Hack) + sz*sizeof(int));
// Allocate a variable-sized structure
p->count = sz;
for (int i = 0; i < sz; i++)
p->fam[i] = i;
32
return p;
}
NEW: C++ does not support flexible array members.
Function name mangling 19
OLD: In order to implement overloaded functions and member functions, C++ compilers must have a
means of mapping the source names of functions into unique symbols in the object code resulting from
the compile. For example, the functions ::foo(int), ::foo(float), and Mine::foo() all
have identical names (foo) but different calling signatures. In order for the linker to distinguish
between the functions during program link time, they must be mangled into different symbolic names.
This differs from the way functions names are mapped into symbolic object names, which allows for
certain cases of type punning (between signed and unsigned integer types) and non-prototyped extern
functions. Therefore programs compiled as C++ will produce different symbolic names, unless the
functions are explicitly declared as having extern "C" linkage. For example:
int
foo(int i);
// Different symbolic names C++
#ifdef __cplusplus
extern "C"
#endif
int bar(int i);
// Same symbolic name in both C and C++
NEW: C++ functions are implicitly declared with extern "C++" linkage
IEC 60559 arithmetic support 20
OLD: allows an implementation to pre-define the __STD_IEC_559 preprocessor macro, indicating
that it conforms to certain required behavior of the IEC 60559 (a.k.a. IEEE 599) specification regarding
floating-point arithmetic and library functions. Implementations that do not pre-define this macro are
not required to provide conforming floating-point behavior. It also allows an implementation to predefine the __STD_IEC_559_COMPLEX preprocessor macro to indicate that it conforms to the
behavior specified by IEC 60559 for complex floating-point arithmetic and library functions. This
affects the way the _Complex and _Imaginary types are implemented.
NEW: C++ does not make any special provisions for implementations that explicitly support the IEC
60559 floating-point specification.
Conformance to IEC 60559 floating-point arithmetic, and the pre-definition of the __STD_IEC_559
macro, is likely to be provided as an extension by many C++ compilers.
C++ provides library functions for complex floating-point arithmetic by providing the complex<>
template class, declared in the standard <complex> header file. Conformance to the complex
arithmetic specification, and the pre-definition of the __STD_IEC_559 macro, might also be provided
by many C++ compilers, and this would indicate how the complex<> template class is implemented.
Inline functions 21
OLD: allows multiple definitions of a given inline function to be different, and does not require the
compiler to detect such differences or issue a diagnostic.
33
NEW: C++ requires all of the definitions for a given inline function to be composed of exactly the same
token sequence.
Integer types headers 22
OLD: provides the header file <stdint.h>, which contains declarations and macro definitions for
standard integer types. For example:
int
int
height(int_least32_t x);
width(uint16_t x);
NEW: C++ does not provide these types or header files
Library header files 23
OLD: adds a few header files that are not included as part of the standard C++ library, though:
<complex.h>
<fenv.h>
<inttypes.h>
<stdbool.h>
<stdint.h>
<tgmath.h>
NEW: Even though C++ provides the standard C library headers as part of its library, it deems their use
as deprecated. Instead, it encourages programmers to prefer the equivalent set of C++ header files
which provide the same functionality as the C header files:
<math.h>
<stddef.h>
<stdio.h>
<stdlib.h>
replaced by
replaced by
replaced by
replaced by
<cmath>
<cstddef>
<cstdio>
<cstdlib>
long long integer type 24
OLD: provides signed long long and unsigned long long integer types to its repertoire of
primitive types, which are binary integer types at least 64 bits wide. It also has enhanced lexical rules to
allow for integer constants of these types. For example:
long long int
unsigned long long int
i = -9000000000000000000LL;
u = 18000000000000000000LLU;
NEW: C++ does not recognize these integer types.
Nested structure tags 25
OLD: Nested structure types may be declared within other structures. The scope of the inner structure
tag extends outside the scope of the outer structure, but does not do so in C++. Structure declarations
possess their own scope in C. This applies to any struct, union, and enumerated types declared within a
structure declaration. For example:
34
struct Outer
{
struct Inner
{
int
a;
float
f;
}
in;
// Nested structure declaration
enum E
// Nested enum type declaration
{
UKNOWN, OFF, ON
}
state;
};
struct Inner
si;
// Not visible in C++
enum E
et;
// Not visible in C++
NEW: In order to be visible in C++, the inner declarations must be explicitly named using its outer
class prefix, or they must be declared outside the outer structure so that they have file scope. The former
case, for example:
// C++ code
Outer::Inner
Outer::E
si;
et;
// Explicit type name
// Explicit type name
Non-prototype function declarations 26
OLD: supports non-prototype (a.k.a. K&R-style) function definitions. For example:
int foo(a, b)
// Deprecated syntax
int a;
int b;
{
return (a + b);
}
NEW: C++ allows only prototyped function definitions. So in order to compile the example above as
C++ code, it must be rewritten in function prototype form:
int foo(int a, int b)
{
return (a + b);
}
Old-style casts 27
NEW: C++ provides four typecast operators:
const_cast
dynamic_cast
reinterpret_cast
static_cast
C++ also provides functional typecasts, which are not recognized in C:
f = float(i);
35
One definition rule 28
OLD: allows tentative definitions for variables, e.g.:
int
int
i;
i = 1;
// Tentative definition
// Explicit definition
NEW: C++ does not allow this. Only one definition of any given variable is allowed within a program.
_Pragma keyword 29
OLD: provides the _Pragma keyword, which operates in a similar fashion to the #pragma
preprocessor directive. For example, these two constructs are equivalent:
#pragma FLT_ROUND_INF
// Preprocessor pragma
_Pragma(FLT_ROUND_INF)
// Pragma statement
NEW: C++ does not support the _Pragma keyword.
Keywords that are not recognized by C++: 30
restrict
_Bool
_Complex
_Imaginary
_Pragma
Reserved keywords in C++ 31
bool
catch
class
const_cast
delete
dynamic_cast
explicit
export
false
friend
mutable
namespace
new
operator
private
protected
public
reinterpret_cast
static_cast
template
this
throw
true
try
typeid
typename
using
virtual
wchar_t
restrict keyword 32
OLD: supports the restrict keyword, which allows for certain optimizations involving pointers. For
example:
void copy(int *restrict d, const int *restrict s, int n)
{
while (n-- > 0)
*d++ = *s++;
}
36
NEW: C++ does not recognize this keyword.
static linkage 33
Both versions allow objects and functions to have static file linkage, also known as internal
linkage. C++, however, deems this as deprecated practice, preferring the use of unnamed namespaces
instead.
The preferred way of doing this in C++ is:
// C++ code
namespace /*unnamed*/
{
static int bufsize = 1024;
static int counter = 0;
static long square(long x)
{
return (x * x);
}
}
String initializers 34
OLD: allows character arrays to be initialized with string constants. It also allows a string constant
initializer to contain exactly one more character than the array it initializes, i.e., the implicit terminating
null character of the string may be ignored. For example:
char
name1[] =
"Harry";
// Array of 6 char
char
name2[6] = "Harry";
// Array of 6 char
char
name3[] =
char
name4[5] = "Harry";
{ 'H', 'a', 'r', 'r', 'y', '\0' };
// Same as 'name1' initialization
// Array of 5 char, no null char
NEW: C++ also allows character arrays to be initialized with string constants, but always includes the
terminating null character in the initialization. Thus the last initializer (name4) in the example above is
invalid in C++.
String literals are const 35
OLD: string literals have type char[n], but are not modifiable (i.e., attempting to modify the contents
of a string literal is undefined behavior).
NEW: In C++, string literals have type const char[n] and are also not modifiable.
Structures declared in function prototypes 36
OLD: allows struct, union, and enum types to be declared within function prototype scope, e.g.:
extern void
foo(const struct info { int typ; int sz; } *s);
37
int bar(struct point { int x, y; } pt)
{ ... }
It also allows structure types to be declared as function return types, as in:
extern struct pt { int x; }
pos(void);
NEW: C++ does not allow either of these, since the scope of the structure declared in this fashion does
not extend outside the function declaration or definition, making it impossible to define objects of that
structure type which could be passed as arguments to the function or to assign function return values
into objects of that type.
Typedefs versus type tags 37
OLD: requires type tags to be preceded by the struct, union, or enum keyword.
NEW: C++ treats type tags as implicit typedef names.
Thus the following code is valid C but invalid C++:
// 0invalid C++
typedef int
type;
struct type
{
type
struct type *
};
memb;
next;
// int
// struct pointer
void foo(type t, int i)
{
int
type;
struct type s;
type = i + t + sizeof(type);
s.memb = type;
}
Variable-argument preprocessor function macros 38
OLD: supports preprocessor function macros that may take a variable number of arguments. Such
macros are defined with a trailing '...' token in their parameter lists, and may use the __VA_ARGS__
reserved identifier in their replacement text.
For example:
#define DEBUGF(f,...) \
(fprintf(dbgf, "%s(): ", f), fprintf(dbgf, __VA_ARGS__))
#define DEBUGL(...) \
fprintf(dbgf, __VA_ARGS__)
int incr(int *a)
{
DEBUGF("incr", "before: a=%d\n", *a);
38
(*a)++;
DEBUGL("after: a=%d\n", *a);
return (*a);
}
NEW: C++ does not provide this feature.
Variable-length arrays (VLAs) 39
OLD: supports variable-length arrays, which are arrays of automatic storage whose size is determined
dynamically at program execution time. For example:
size_t sum(int sz)
{
float
arr[sz];
while (sz-- > 0)
arr[sz] = sz;
return sizeof(arr);
// VLA, dynamically allocated
// Evaluated at runtime
}
NEW: C++ does not support VLAs.
Void pointer assignments 40
OLD: allows a pointer to void (void *) value to be assigned to an object of any other pointer type
without requiring a cast. This allows such things as assigning the return value of malloc() to a
pointer variable without the need for an explicit cast.
NEW: C++ does not allow assigning a pointer to void directly to an object of any other pointer type
without an explicit cast. This is considered a breach of type safety, so an explicit cast is required.
Wide character type 41
OLD: provides a wide character type, wchar_t, that is capable of holding a single wide character
from an extended character set. This type is defined in the standard header files <stddef.h>,
<stdlib.h>, and <wchar.h>.
NEW: C++ also provides a wchar_t type, but it is a reserved keyword just like int. No header file is
required to enable its definition.
Additional Changes from C to ANSI C++
Aggregate Initializers 42
C requires automatic and register variables of aggregate type (struct, array, or union) to have initializers
containing only constant expressions. (Many compilers do not adhere to this restriction, however.)
C++ allows non-constant expressions to be used in initializers for automatic and register variables. (It
39
also allows arbitrary non-constant expressions to be used to initialize static and external variables.)
For example:
// C and C++ code
void foo(int i)
{
float
x = (float)i;
int
m[3] = { 1, 2, 3 };
int
g[2] = { 0, i };
}
// Valid C90, C99, and C++
// Valid C90, C99, and C++
// Invalid C90
Comments 43
C++ recognizes //... comments as well as /*...*/ comments.
Conly recognizes the /*...*/ form of comments. The //... form usually produces a syntax error in
C, but there are rare cases that may compile erroneously without warning:
i = (x//*y*/z++
, w);
Conditional expression declarations 44
C++ allows local variable declarations within conditional expressions (which appear within for, if,
while, and switch statements). The scope of the variables declared in this context extends to the end
of the statement containing the conditional expression. For example:
for (int i = 0; i < SIZE; i++)
a[i] = i + 1;
C does not allow this feature.
Digraph punctuation tokens 45
C++ recognizes two-character punctuation tokens, called digraphs, which are not recognized by C. The
digraphs and their equivalent tokens are:
<:
:>
<%
%>
%:
%:%:
[
]
{
}
#
##
Implicit function declarations
46
C allows a function to be implicitly declared at the point of its first use (call), assigning it a return type
of int by default. For example:
/* No previous declaration of bar() is in scope */
void foo(void)
{
bar(); /* Implicit declaration: extern int bar() */
}
C++ does not allow implicit function declarations. It is invalid to call a function that does not have a
40
previous declaration in scope.
C no longer allows functions to be implicitly declared. The code above is invalid in C++.
C recognizes the same set of digraphs.
The following program is valid in C++:
%:include <stdio.h>
%:ifndef BUFSIZE
%:define BUFSIZE
%:endif
512
void copy(char d<::>, const char s<::>, int len)
<%
while (len-- >= 0)
<%
d<:len:> = s<:len:>;
%>
%>
Implicit variable declarations
47
C allows the declaration of a variable, function argument, or structure member to omit the type specifier,
implicitly defaulting its type to int.
C++ does not allow this omission.
The following code is valid in C, but invalid in C++:
static
sizes = 0;
struct info
{
const char *
const
};
/* Implicit int, error */
name;
sz;
static foo(register i)
{
auto j = 3;
/* Implicit int, error */
/* Implicit ints, error */
/* Implicit int, error */
return (i + j);
}
Intermixed declarations and statements
48
C syntax specifies that all the declarations within a block must appear before the first statement in the
block.
C++ does not have this restriction, allowing statements and declarations to appear in any order within a
block.
void prefind(void)
41
{
int
i;
for (i = 0; i < SZ; i++)
if (find(arr[i]))
break;
const char *
s;
/* Invalid C90, valid C99 and C++ */
s = arr[i];
prepend(s);
}
42
Download