🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Eugene Lazutkin Thu, 08 Feb 1996 17:55
Portability. Modules. WAS: RE: Are all Windows programs ill-formed?
#3289
Author: Eugene Lazutkin
Date: Thu, 08 Feb 1996 17:55
134 lines
5908 bytes
On 	Tuesday, February 06, 1996 9:18 PM, 
rich@kastle.com (Richard Krehbiel) wrote:
> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:
> 
> >I did not claim that any or all Windows compilers were not conforming.
> >I simply pointed out what they were required to do in order to conform.
> 
> >I did say that
> 
> >| I think the problem is due to Microsoft overlooking the C and C++
> >| standards, not vice versa.
> 
> >but the problem I was referring to was not that Microsoft's compilers
> >don't conform to the standard (most likely they do) but rather that
> >Microsoft encourages people to write non-portable, non-standard-conforming
> >code which is then subject to the usual problems of vendor lock-in.
> 
> YES, YES, YES.  This is IT.
> 

If you use Windows GUI => your program is non-portable by definition, 
because your use vendor-specific libraries.  Under these circumstances 
I personally don't care about portability and how my main function looks 
like.

This is not a matter of a portability! If you don't have a portable library 
(GUI, math, network & Co.), your program will be non-portable anyway.

Current (and future :-( ) standard doesn't cover a very important topic: 
libraries.  A library is not a bunch of somehow related (or unrelated) 
functions. Sometimes you need initialize your library and clean up after 
termination.  Shared libraries raise more complex questions.  Of course, 
I want to enjoy the benefits of DLLs (dynamic link libraries). In this case 
my library will be Windows-specific.

If I want to write a portable program in Windows, I write console-mode
program (without any GUI) and use just standard iostream.h for an
interaction with a user. It is a portable way, but usually it is not
suitable for end users.

About the main() function.  A Windows compiler (MS, Borland, Symantec,
Watcom) doesn't check its presence. Linker does. It knows the name of
an entry point.  Standard library contains some sort of proxy with this
name which calls main() or whatever. So it is a matter of a proxy for a
linker.  You may think that main() is buried in the standard Windows
library and it will call WinMain(). That's it, you use the main()
implicitly.

BTW, the same can be applied to the Unix (MacOS) platform.  X-based
(Motif-based, Fresco-based,...) program are not portable either unless
you have the specific GUI implementation for your target platforms.

Another point of non-portability is #pragmas.  Static containers are
almost useless unless you can specify the order of their
construction/destruction.  Borland provides you with #pragma
startup/exit (am I correct with names?). With this tool you can specify
a priority. It is not a ultimate medicine but it helps a lot!

If you use a static container with some statically included items (by
their constructors), your objects will be well-formed automatically in
most cases (I mean practical cases):

static Container  list(); // The constructor of this list has higher priority 
			  // than item's constructor. You do this trick
			  // with a #pragma.
static Item	item1( list );	// All items are located in different files.
static Item	item2( list );	// The item's constructor includes an item
				// into a list.
/* ... */
static Item	itemN( list );

// file with the main() function
void	main() {				
	/* ... */
	// lets check all items
	CHECK_ALL_ITEMS( list );
	/* ... */
}

Alternative way: include all items into the container manually and
don't forget to do this initialization every time when you use this
container in your program.

static Container  list();

static Item	item1();	// All items are located in different files.
static Item	item2();
/* ... */
static Item	itemN();

// file with the main() function
// you have to include here the declarations of all items!
void	main() {				
	/* ... */
	// initialization of list, all items should be visible here! 
	list.include( item1 );
	list.include( item2 );
	/* ... other includes ... */
	list.include( itemN );
	/* ... */
	// lets check all items
	CHECK_ALL_ITEMS( list );
	/* ... */
}

If you add a new item, you should add one more file in 1st case.  In
2nd case you have to modify several places in your program. And this is
a potential source of errors.

Of course, this is just an example, but this is a real-live example. I
meet these cases every my project.

I don't think that WinMain() is a serious source of incompatibility and
non-portability.  I think that the main source is vendor-specific
libraries (we can't do anything with that) and the obvious weakness of
C++ standard in the modularization of programs. We don't have the
strong definition of the module, how it can be controlled by us
programmers (initialization, deinitialization, reusing by different
threads and/or programs) and how we can create well-formed static
structures and conglomerates.

If we don't solve these problems, we will have non-portable
applications. This is not a just language level.  This is a level ov
C++ machine, how it works, C++ environment.

Thanks for patience


Eugene Lazutkin
eugene@int.com
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  Moderation policy:
  http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads