Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++ kernel linker problems - help please!

117 views
Skip to first unread message

Carl Mette

unread,
Dec 19, 2000, 7:42:45 PM12/19/00
to
Hi,
I'm trying to build a C++ driver using the NuMega C++ Run Time Support
for NT/WDM Kernel Mode Drivers methodology. Everything seems to compile
and link fine except when I use an STL class called CStdStr in StdStr.h.
(created by Joe O'Leary -
http://home.earthlink.net/~jmoleary/projects.htm) CStdStr class is a
substitution for the MFC class CString.
I can compile and link fine in a user space defined project. However, if
I try to use it in the kernel I get these strange linker errors which
relate to the constructor and destructor.
Does anyone have any ideas what could be wrong?
Thanks for any help you can send my way!


#include "K_AccessProfile.h"
#include "StdString.h"

class CKernelAccessProfile
{
public:
CKernelAccessProfile();
~CKernelAccessProfile();
};

CKernelAccessProfile::CKernelAccessProfile()
{
CStdStr<TCHAR> x;
}

CKernelAccessProfile::~CKernelAccessProfile()
{
return ;
}


BUILD OUTPUT:

Setting SDK environment relative to D:\SDK. Targeting Windows NT (i386)
Setting DDK Build Environment.
build in directory . with arguments -buildopts (basedir D:\DDK)
run build -e -Z -M for checked version in .
BUILD: Compile and Link for i386
BUILD: Compiling d:\instantoffice_4.0\platform\pbx\cplusdrv directory
Compiling - k_accessprofile.cpp for i386
Building Library - i386\checked\vnidba.lib for i386
BUILD: Linking d:\instantoffice_4.0\platform\pbx\cplusdrv directory
Linking Executable - i386\checked\vnidba.sys for i386
k_accessprofile.obj() : error LNK2001: unresolved external symbol
"__declspec(dllimport) public: __thiscall std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char>
>::~basic_string<char,struct std::char_traits<char>,class std
::allocator<char> >(void)"
(__imp_??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ)

k_accessprofile.obj() : error LNK2001: unresolved external symbol
"__declspec(dllimport) public: __thiscall std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char>
>::basic_string<char,struct std::char_traits<char>,class std:
:allocator<char> >(class basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >::allocator<char>
const &)"
(__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@ABV?$allocator@D@1@@Z)

i386\checked\vnidba.sys() : error LNK1120: 2 unresolved externals
BUILD: Done
1 files compiled - 15 Warnings
1 libraries built
1 executables built - 3 Errors
=============== build warnings ======================
C:\Progra~1\Micros~2\VC98\INCLUDE\istream(547) : warning C4530: C++
exception handler used, but unwind semantics are not enabled. Specify
-GX
C:\NuMega\DriverStudio\DriverWorks\include\util.h(59) : warning C4666:
'int __cdecl abs(int)' : function differs from ' __stdcall abs()' only
by calling convention
C:\Progra~1\Micros~2\VC98\INCLUDE\ostream(234) : warning C4530: C++
exception handler used, but unwind semantics are not enabled. Specify
-GX
C:\Progra~1\Micros~2\VC98\INCLUDE\ostream(234) : warning C4530: C++
exception handler used, but unwind semantics are not enabled. Specify
-GX
C:\Progra~1\Micros~2\VC98\INCLUDE\istream(46) : warning C4530: C++
exception handler used, but unwind semantics are not enabled. Specify
-GX
C:\Progra~1\Micros~2\VC98\INCLUDE\istream(46) : warning C4530: C++
exception handler used, but unwind semantics are not enabled. Specify
-GX
.\xstring(525) : warning C4530: C++ exception handler used, but unwind
semantics are not enabled. Specify -GX
.\xstring(525) : warning C4530: C++ exception handler used, but unwind
semantics are not enabled. Specify -GX


build complete

VniDba.sys - 3 error(s), 8 warning(s)

Mark Roddy

unread,
Dec 19, 2000, 10:07:20 PM12/19/00
to
You cannot use C++ exception handlers in the kernel as there is no
runtime support for the various C++ exception handling functions
emitted by the compiler. Neither my kernel C++ runtime library
(www.hollistech.com) nor I think Numega's provide this level of
runtime support.

Good luck though on porting STL into the kernel.

=
Mark Roddy
WindowsNT Windows2000 Consultant
Hollis Technology Solutions
http://www.hollistech.com
mailto:in...@hollistech.com

billy_dr...@my-deja.com

unread,
Dec 19, 2000, 10:28:01 PM12/19/00
to
Nor does WinDK's. You can use the Microsoft specific __try and
__except at PASSIVE_LEVEL.

Bill M.


Sent via Deja.com
http://www.deja.com/

Gary Nebbett

unread,
Dec 20, 2000, 5:55:07 AM12/20/00
to
http://www.deja.com/getdoc.xp?AN=648586436&fmt=text describes an approach to C++ exception handling
in kernel mode.

Gary

Joshua Schaeffer

unread,
Dec 26, 2000, 2:30:57 AM12/26/00
to
The kernel seems like the last place on earth that someone would want to
find a C++ class library implementation.

Felix Kasza [MVP]

unread,
Dec 26, 2000, 4:17:58 PM12/26/00
to
Joshua,

> The kernel seems like the last place on earth that someone
> would want to find a C++ class library implementation.

I am not opposed to seeing C++ in KMDs, as long as the C++ is used as an
enhanced C. In other words, I am not keen on vtables (would even half of
the driver writers know how to force the compiler to put them in
non-paged memory) or exceptions (on an 8K stack, hahaha), nor do I ever
wish to see some bloated class instance passed by value. But as
syntactical sugar, to replace stuff like HFOO FooCreate(),
FooDoSomething(hFoo), FooDelete(hFoo) -- why not?

--

Cheers,
Felix.

If you post a reply, kindly refrain from emailing it, too.
Please consider migrating to microsoft.public.platformsdk.*
where the MS folks plan on hanging around. See you there!

Carey Gregory

unread,
Dec 26, 2000, 5:11:05 PM12/26/00
to
"Felix Kasza [MVP]" <fel...@mvps.org> wrote:

>I am not opposed to seeing C++ in KMDs, as long as the C++ is used as an
>enhanced C. In other words, I am not keen on vtables (would even half of
>the driver writers know how to force the compiler to put them in
>non-paged memory) or exceptions (on an 8K stack, hahaha), nor do I ever
>wish to see some bloated class instance passed by value. But as
>syntactical sugar, to replace stuff like HFOO FooCreate(),
>FooDoSomething(hFoo), FooDelete(hFoo) -- why not?

I agree. There's nothing wrong with C++ in system code, but there are
programmers who shouldn't be writing system code. The problem is
usually one of not fully understanding how a compiler actually
implements all the whiz-bang language features and therefore not
knowing which ones are going to spell doom in a kernel mode
environment.


--
Carey Gregory

billy_dr...@my-deja.com

unread,
Dec 27, 2000, 1:20:31 PM12/27/00
to
Obviously NuMega and BlueWater Systems, (now BSquare), have used C++ in
kernel space quite successfully. Once the benefits of C++ have been
embraced, it is really hard to see why one would ever want to use C in
a kernel environment. The only successful argument that could be made
for this is binary size, which for the vast majority of MS Windows
environments is a non-issue. Speed is just a farce, one can make just
as fast a kernel mode driver in C++ as C everytime, (provided of course
one knows how to use C++ correctly). C++ is just the better choice.
Unless of course one likes C's sparse number of abstractions of
unnecessary detail, or the increased time to market, or rewriting the
same code over and over,...

Bill M.

Gary G. Little

unread,
Dec 27, 2000, 8:15:44 PM12/27/00
to
<billy_dr...@my-deja.com> wrote in message
news:92dbt8$kti$1...@nnrp1.deja.com...

> Obviously NuMega and BlueWater Systems, (now BSquare), have used C++ in
> kernel space quite successfully. Once the benefits of C++ have been
> embraced, it is really hard to see why one would ever want to use C in
> a kernel environment. The only successful argument that could be made
> for this is binary size, which for the vast majority of MS Windows
> environments is a non-issue. Speed is just a farce, one can make just
> as fast a kernel mode driver in C++ as C everytime, (provided of course
> one knows how to use C++ correctly). C++ is just the better choice.
> Unless of course one likes C's sparse number of abstractions of
> unnecessary detail, or the increased time to market, or rewriting the
> same code over and over,...
>
> Bill M.
>
Hell, Billy, we used to say that about assembly!!


Maxim S. Shatskih

unread,
Dec 28, 2000, 2:41:50 PM12/28/00
to
> kernel space quite successfully. Once the benefits of C++ have been
> embraced, it is really hard to see why one would ever want to use C in
> a kernel environment. The only successful argument that could be made
> for this is binary size, which for the vast majority of MS Windows
> environments is a non-issue. Speed is just a farce, one can make just
> as fast a kernel mode driver in C++ as C everytime, (provided of course

C++ has lots of compiler-generated hidden stuff and hidden semantics - which
are not good in the driver.

Max


Muzaffer Kal

unread,
Dec 28, 2000, 5:04:36 PM12/28/00
to

There is no magic; there is either semantics you understand and there
is semantics you don't understand. Everyone knows that ptr++
increments a ULONG* differently than a CHAR*. You just have to learn
more. You can suppress all the unwanted stuff from the compiler. C++
compilers are (mostly :-( deterministic beasts. There is standard and
msft docs about all the intricate details on how things work. If one
bothers to read/understand these, the "hiddenness" goes away. IMHO,
the effort to understand the C++ language/compiler is worth the
productivity gain. But again, that's my opinion; you are entitled to
your own.

Muzaffer

FPGA DSP Consulting
http://www.dspia.com

Maxim S. Shatskih

unread,
Dec 28, 2000, 10:50:07 PM12/28/00
to
> There is no magic; there is either semantics you understand and there
> is semantics you don't understand. Everyone knows that ptr++
> increments a ULONG* differently than a CHAR*. You just have to learn
> more. You can suppress all the unwanted stuff from the compiler. C++
> compilers are (mostly :-( deterministic beasts. There is standard and
> msft docs about all the intricate details on how things work. If one
> bothers to read/understand these, the "hiddenness" goes away. IMHO,
> the effort to understand the C++ language/compiler is worth the
> productivity gain. But again, that's my opinion; you are entitled to
> your own.

This is true, but it's a matter of taste.
I prefer C for kernel mode work. I don't want any C++ classes to hide the
kernel API from me. (though there is a strong temptation to wrap the
UNICODE_STRING with a class).
As for user-mode work - C++ is great. CString alone is a good cause to use
C++ in user mode. Not to say on COM/ATL.
MFC's windowing is (usually, not always) useful too.

Max


Carey Gregory

unread,
Dec 29, 2000, 1:30:40 PM12/29/00
to
"Maxim S. Shatskih" <ma...@storagecraft.com> wrote:

C++ is one thing, but I would consider the MFC nothing short of the
kiss of death in kernel mode. I'd sooner stick myself in the eye with
a sharp stick than try to use the MFC in kernel mode.

There's nothing about C++ that hides the kernel API. You seem to be
assuming that C++ == MFC, and as much as MS might like for the world
to think that, it just isn't so.

There's much to be gained from the features of C++, but that doesn't
mean you have to exploit them all, or even should. Many simple things
like being able to specify default values for function parameters,
declaring variables where you use them, more robust type casting and
checking, etc.... these are all useful regardless of whether you're
writing for user or kernel mode.

--
Carey Gregory

billy_dr...@my-deja.com

unread,
Dec 29, 2000, 4:07:52 PM12/29/00
to
This debate borders on religious, but I will throw in my last $0.02
anyway and be done with it. C++ has many strengths over C and no real
weaknesses. Most of the strengths are as much if not more useful in
kernel space as in user space. Strong type checking is not the least
of these. C++ is in some respects more complicated, but it is a tool
just like any other, and once mastered can provide many benefits. If
one can learn kernel-mode programming for WDM, I would argue that C++
is trivial. Further, the C++-isms such as compiler genererated
constructors and the like are easily avoided, all that is required is a
strong knowledge of C++. Most of the arguments against C++ are made
from and by a lack of knowledge of the workings of C++. I have
personally generated numerous C++ drivers, and I have and would put
them up against C counterparts any day. I have seen others I have
worked with generate extrememly fast PCI display drivers and the like
with C++ and I have never seen C++ in the hands of those who know how
to use it, cause a problem with speed, or any other unique problems for
that matter. To not prefer it is a personal choice, but I have yet to
see any reasoned or reasonable arguments that would be persuasive for C
over C++. I doubt any could exist aside from a time problem arising
from a lack of C++ knowledge, and then I would argue it would be
worthwhile to take the time and learn C++. I came from an Assembly/C
background and absolutely hated C++ while I was learning it, but have
grown to see the enormous benefits of it. I would never use C now
unless forced to do so. The class structure does not inherently hide
the kernel APIs either, that would be a product of bad class design.
Take a look at WinDK from BSquare and you will see a set of classes
that are useful yet unobtrusive. You can use WinDK functionality, yet
still make any kernel call you wish at any point. Bad use of the
features of the language have given C++ a bad name. But, it is not
inherently bad, it is just a more robust tool, that takes more care to
master.

Bill M.


> This is true, but it's a matter of taste.
> I prefer C for kernel mode work. I don't want any C++ classes to hide
the
> kernel API from me. (though there is a strong temptation to wrap the
> UNICODE_STRING with a class).
> As for user-mode work - C++ is great. CString alone is a good cause
to use
> C++ in user mode. Not to say on COM/ATL.
> MFC's windowing is (usually, not always) useful too.
>
> Max
>
>

Maxim S. Shatskih

unread,
Dec 29, 2000, 2:20:13 PM12/29/00
to
> C++ is one thing, but I would consider the MFC nothing short of the
> kiss of death in kernel mode. I'd sooner stick myself in the eye with
> a sharp stick than try to use the MFC in kernel mode.

I too.

> There's nothing about C++ that hides the kernel API. You seem to be
> assuming that C++ == MFC, and as much as MS might like for the world
> to think that, it just isn't so.

No. I don't think so.

> There's much to be gained from the features of C++, but that doesn't
> mean you have to exploit them all, or even should. Many simple things
> like being able to specify default values for function parameters,
> declaring variables where you use them, more robust type casting and
> checking, etc.... these are all useful regardless of whether you're
> writing for user or kernel mode.

This is true, but there are C++ features like multiple inheritance which
open a huge area for abusive programming style and producing unreadable
code. C code is much, much more readable and intuitive.

Max


Carey Gregory

unread,
Dec 29, 2000, 8:08:49 PM12/29/00
to
"Maxim S. Shatskih" <ma...@storagecraft.com> wrote:

>This is true, but there are C++ features like multiple inheritance which
>open a huge area for abusive programming style and producing unreadable
>code. C code is much, much more readable and intuitive.

But since the processor and the operating system know nothing about
readability and intuitiveness, it boils down to a religious debate. My
feeling on abusive programming style is that abusive programmers should be
hanged in the public square, so I guess we'll just have to agree to
disagree.


--
Carey Gregory

Maxim S. Shatskih

unread,
Dec 29, 2000, 8:18:59 PM12/29/00
to
> But since the processor and the operating system know nothing about
> readability and intuitiveness, it boils down to a religious debate.

Surely.
I worked on C++ since 93 (user mode - OWL/MFC windowing, MFC/ATL COM
components, SQL database access) - but I don't like the idea of writing
drivers in it. I saw one driver source with WinDK - IMHO just terrible,
though this is a matter of taste.

> feeling on abusive programming style is that abusive programmers should be
> hanged in the public square, so I guess we'll just have to agree to

IMHO "abusive programming style" is using as much smart language constructs
as possible to get the job done, thus sacrificing the code readability.

Max


Mark Roddy

unread,
Dec 29, 2000, 9:16:19 PM12/29/00
to
On Tue, 26 Dec 2000 21:17:58 +0000, "Felix Kasza [MVP]"
<fel...@mvps.org> wrote:

>Joshua,
>
> > The kernel seems like the last place on earth that someone
> > would want to find a C++ class library implementation.
>
>I am not opposed to seeing C++ in KMDs, as long as the C++ is used as an
>enhanced C. In other words, I am not keen on vtables (would even half of
>the driver writers know how to force the compiler to put them in
>non-paged memory) or exceptions (on an 8K stack, hahaha), nor do I ever
>wish to see some bloated class instance passed by value. But as
>syntactical sugar, to replace stuff like HFOO FooCreate(),
>FooDoSomething(hFoo), FooDelete(hFoo) -- why not?


Do you have any evidence that vtables are not by default in non-paged
pool?

I don't use C++ exceptions, but the regular SEH exceptions have
similar stack issues. There is no runtime support for C++ exceptions
anyway, so one would have to go to a lot of trouble to get it working.

However, I have seen a whole lot of NT drivers, especially W2K bus
drivers, that are screaming for an object oriented class based
approach to what I will call the "device object routing problem".

I get hives every time I see some code segment doing something like:

if (commonDeviceExtension->deviceExtensionType == ImAnFdo) {

FDO_DEVICE_EXTENSION fdoExtension = (FDO_DEVICE_EXTENSION)
deviceExtension;

doTheBusDriverFdoOperation(fdoExtension, Irp);

} else {

ASSERT(commonDeviceExtension->deviceExtensionType == ImAPdo);

PDO_DEVICE_EXTENSION pdoExtension = (PDO_DEVICE_EXTENSION)
deviceExtension;

doTheBusDriverPdoOperation(pdoExtension, Irp);

}

instead of:

baseDeviceExtensionClass->BusDriverOperation(Irp);

Take a look at the disk class driver, for example.

I mean really, this type of incessant routing code is one of the
reasons why C++ was invented. It is fragile, error prone, inefficient
and FUGLY.

And, by the way, I've seen other bus drivers that invent their own
dispatch tables to handle the routing problem. Gee what's the
difference between that and a class-based approach, other than the
compiler will do a better job of it?

Carey Gregory

unread,
Dec 30, 2000, 4:41:43 PM12/30/00
to

"Maxim S. Shatskih" <ma...@storagecraft.com> wrote:

>IMHO "abusive programming style" is using as much smart language constructs
>as possible to get the job done, thus sacrificing the code readability.

I think we agree on that. One of the signs of an immature programmer is one
who chooses obscure, complex methods over simple, obvious methods simply
because he can. The KISS principle has always applied and always will.

Think of C++ as a power saw and C as a hand saw. You can hurt yourself a
lot faster and a lot worse with a power saw, but in the right hands you can
saw a heck of a lot more wood.


--
Carey Gregory

Felix Kasza [MVP]

unread,
Dec 30, 2000, 5:20:07 PM12/30/00
to
Mark,

> Do you have any evidence that vtables are not by
> default in non-paged pool?

Not either way -- and until I do, I shall just assume the worst. That
has served me well for writing drivers. :)

> [...] the regular SEH exceptions have similar
> stack issues.

Here I disagree. I have yet to see a large (working) driver that uses
SEH as its main way to error out of an operation, while I have seen (and
written) plenty of code that deliberately uses throw.

> baseDeviceExtensionClass->BusDriverOperation(Irp);

An excellent example. To use your words, do _you_ have any evidence that


vtables are not by default in non-paged pool?

If you, you would save me (and presumably a lot of others) some time,
promote healthy, robust code, and put an end to this particular aspect
of the C++-in-KM debate. Please?

Maxim S. Shatskih

unread,
Dec 31, 2000, 11:15:53 AM12/31/00
to
> Here I disagree. I have yet to see a large (working) driver that uses
> SEH as its main way to error out of an operation, while I have seen (and

FASTFAT from IFS Kit relies on __try/__catch heavily to do nearly all error
condition processing.

Max


Maxim S. Shatskih

unread,
Dec 31, 2000, 11:14:03 AM12/31/00
to
> I think we agree on that. One of the signs of an immature programmer is
one
> who chooses obscure, complex methods over simple, obvious methods simply
> because he can. The KISS principle has always applied and always will.

Yes, we agree on that.

> Think of C++ as a power saw and C as a hand saw. You can hurt yourself a
> lot faster and a lot worse with a power saw, but in the right hands you
can
> saw a heck of a lot more wood.

Let's imagine the C++ class (and inheritance) based toolkit which wraps
around the kernel.

In C:
- I need to know the kernel pecularities and dangerous places.
With this toolkit:
- I need to know both the kernel pecularities and dangerous places and the
toolkit's ones. I also need to know how toolkit's C++ classes wraps around
the kernel's callbacks and structures.

This is surely a drawback. NT kernel is far from being awkward and hardly
usable - so, I don't think there are any advantages from such a toolkit.
On the other hand, say, user32 API with its WndProc and hundreds of WM_XXX
is hardly usable - thus, wrapping it in C++ classes is a good idea. Thus -
MFC.

Anyway this is matter of taste :-)

Max


Mark Roddy

unread,
Jan 1, 2001, 12:54:25 AM1/1/01
to
On Sat, 30 Dec 2000 22:20:07 +0000, "Felix Kasza [MVP]"
<fel...@mvps.org> wrote:

>Mark,
>
> > Do you have any evidence that vtables are not by
> > default in non-paged pool?
>

>If you, you would save me (and presumably a lot of others) some time,
>promote healthy, robust code, and put an end to this particular aspect
>of the C++-in-KM debate. Please?

I didn't raise this apparent non-issue, you did. My assumption is that
all kernel code and data is in non-paged pool unless it is explicitly
marked as pageable. I base this assumption on various statements in
the DDK and elsewhere that say something like: "all kernel code and
data is non-paged unless it is explicitly marked as pageable".

It is a bit unsettling to have someone say, as you did, that:

>>> I am not keen on vtables (would even half of
>>>the driver writers know how to force the compiler to put them in
>>>non-paged memory)

You appeared to be claiming that there is SOME PROBLEM WITH VTABLES re
which section they are in, and that unless one takes mysterious
special measures, BAD THINGS WILL HAPPEN.

Now you appear to be saying that in fact you have no clue if there is
a problem or what section vtables are in.

Thanks a lot :-)

Well, vtables are just initialized data, and like ALL INITIALIZED DATA
in the kernel, unless you create a segment that is marked as pageable,
it is nonpaged. See various statements to this effect in the DDK.

I've gone and dumped and also mapped a c++ driver (that runs just
fine, thanks,) and unless the vtables are in INIT, which I rather
doubt, they are safely plunked down in .rdata, exactly where they
belong. There simply aren't any pageable code or data sections in this
driver, (only non-paged or discardable, as one would expect,) and it
is making extensive use of virtual functions.

My theory about this (non-)issue is that as it is difficult to prove
that somehow vtables aren't mysteriously pushed into a pageable data
section, given that one would have to go and disassemble the driver
just to figure out what the name of a specific vtable was and where it
might be located, it gets raised by people who simply have some sort
of intuitive fear of C++ in the kernel. It is a good story: the evil
c++ compiler is generating HIDDEN TABLES and since it doesn't KNOW
that the kernel doesn't naturally like paged data, the evil c++
compiler MIGHT create a pageable data segment just TO BE EVIL. Of
course the evil c++ compiler would have to know that it ought to emit
the pragma's that inform the linker to create pageable data sections
as the linker defaults to always creating non-pageable data (and code)
sections, but that is a mere detail.

There aren't any pageable code or data sections in your driver unless
you explicitly create one. End of story.

Carey Gregory

unread,
Jan 1, 2001, 4:55:07 PM1/1/01
to

"Maxim S. Shatskih" <ma...@storagecraft.com> wrote:

>Let's imagine the C++ class (and inheritance) based toolkit which wraps
>around the kernel.

Obvious question: Why wrap the kernel API with a class at all?


--
Carey Gregory

billy_dr...@my-deja.com

unread,
Jan 1, 2001, 6:24:55 PM1/1/01
to
I doubt from your arguments here that you really know C++ all that
well, no offense. But, yes C++ classes do take a little more upfront
effort to learn, but saying that there is no gain from that effort is
just plain idiocy. I don't believe that is opinion. You knocked
WinDK, what exactly was awful about the source you saw? You didn't
understand it? Spend a month using it and see what you think then. If
you haven't done this, then you really have no room to speak. C++
ain't C, it is much more powerful and robust, but a lot of C
programmers have the predjudices you display. Comparing MFC to
anything in kernel mode is just ridiculous. You cannot sit there and
tell me that the bloat and obfuscation caused by MFC is anything
resembling a toolkit like WinDK or Driver Works. With WinDK you can
make any kernel call at anytime. Further, looking over WinDK, I can
read and understand any of its samples in about a tenth of the time I
can any of the DDK samples. That is to be expected though as it is
meant to be understandable and the DDK samples are just meant to work.
This whole debate IS religious, but that is unfortunate. An assembly
language programmer could make these same arguments about Assembly vs.
C and be just as correct as you are, and that is not very. Don't mean
to be rude, but C++ has been around what, over 12 years now in
mainstream, and the embedded and systems communities seem to be a
little slow in the uptake. I came from an Assembly/C background
myself, but it took me all of about 6 months to realize the superiority
of C++ over either of those languages for the large majority of the
systems code I write. I don't understand why most system level
programmers don't see it. I can reach only one conclusion.

Bill M.


> In C:
> - I need to know the kernel pecularities and dangerous places.
> With this toolkit:
> - I need to know both the kernel pecularities and dangerous places
and the
> toolkit's ones. I also need to know how toolkit's C++ classes wraps
around
> the kernel's callbacks and structures.
>
> This is surely a drawback. NT kernel is far from being awkward and
hardly
> usable - so, I don't think there are any advantages from such a
toolkit.
> On the other hand, say, user32 API with its WndProc and hundreds of
WM_XXX
> is hardly usable - thus, wrapping it in C++ classes is a good idea.
Thus -
> MFC.
>
> Anyway this is matter of taste :-)
>
> Max
>
>

Tomas Restrepo

unread,
Jan 1, 2001, 6:40:59 PM1/1/01
to
Carey,

> >Let's imagine the C++ class (and inheritance) based toolkit which wraps
> >around the kernel.
>
> Obvious question: Why wrap the kernel API with a class at all?

While I agree on principle with Maxim's and your comments about the use of
complex methods where they are not needed, I don't think that's reason
enough to just shun away C++, even in kernel mode. After all, if you're
gonna write a kernel toolkit, it needs careful analisis and design, just
like any other piece of software, and I do think that a properly written one
could benefit kernel developers.

That said, the kernel is definitely not the place for a huge toolkit or
framework. The kind of wrapper classes I'd use in a kernel mode driver would
be primarily lightweight wrappers. For example, use them to ensure proper
resource clean up.

What I don't completely agree with, is Maxim's observation:


<<
With this toolkit:
- I need to know both the kernel pecularities and dangerous places and the
toolkit's ones. I also need to know how toolkit's C++ classes wraps around
the kernel's callbacks and structures.
>>

Two basic reasons:
- The primary reason to write any kind of toolkit/framework, imho, is to add
another level of abstraction either to: a) add flexibility, and/or b) make
things simpler.
- In most frameworks, you do have to be aware of what lies beneath. Just how
aware you need to be depends on the level of abstraction provided by the
framework.

If the framework provides a high level of abstraction, and you still _need_
deep knowledge of what's going on behind it, chances are the framework is
poorly designed. (Having that deep knowledge does help most of the time,
though). OTOH, if the framework does not provide a high level of
abstraction, then it's likely that it's not very complex, so it's no big
deal, anyway.

(and in case anyone is wondering, I don't consider MFC an example of a very
good framework, although it does have it's strong points).

--
Tomas Restrepo [VC++ MVP]
tom...@mvps.org
http://www.mvps.org/windev/

Maxim S. Shatskih

unread,
Jan 1, 2001, 11:51:38 PM1/1/01
to
> - The primary reason to write any kind of toolkit/framework, imho, is to
add
> another level of abstraction either to: a) add flexibility, and/or b) make
> things simpler.

My statement was:
- this another layer of abstraction in the kernel usually has small benefits
and large drawbacks - it increases the complexity instead of decreasing it.

Max


Maxim S. Shatskih

unread,
Jan 2, 2001, 12:15:51 AM1/2/01
to
> I doubt from your arguments here that you really know C++ all that
> well, no offense.

Just your opinion.
C++ is convinient for stuff like CString or for COM objects. I also
participated in large C++ based projects. But anyway I do not like the idea
of writing kernel-mode code in C++.
For instance, the usual C++ approach will have the consequence of allocating
huge number of tiny class instances - this leads sometimes to poor
performance even in large user-mode apps (we wrote the OO database in C++
around the SQL server about 4 years ago. The performance was bad and we were
forced to use optimizations to avoid allocating all class instances by
new(...). This optimization did not make the code more readable).

Or, well, let's imagine things like STL's vectors and MFCs CStringArray.
Sorry, but I prefer RtlxxxGenericTable and InsertTailList to these things.
The reason is that C++ container classes impose heavy burden on the
allocator - constant allocations/reallocations of the array body are not so
cheap.
As about the kernel's primitives - the list node or the table entry can
usually be allocated as a part of the larger structure - thus diminishing
the burden on the allocator.

>But, yes C++ classes do take a little more upfront
> effort to learn, but saying that there is no gain from that effort is
> just plain idiocy. I don't believe that is opinion. You knocked
> WinDK, what exactly was awful about the source you saw?

The PnP and power IRP processing paths become just unreadable - scattered
between the framework's code and the driver's code - just for instance.
Also:
- in C, if I want to allocate structures from the lookaside, I just call
ExAllocateFromNPagedLookasideList.
- in the classic C++ approach, I must declare the operator new() in order to
do this. Thus, the allocation logic becomes scattered over the class
declaration and the caller code.
Why not follow the KISS principle and keep all this logic in one place?

Maybe this is my fault than when somebody says "C++", I recall the
well-known approach of allocating huge number of different class instances
by new(...), which has its drawbacks. Yes, it is another layer of
abstraction - but has its cost of heavy burden imposed on the allocator.
The "usual" C++ way is to use inheritance at all possible places - not so
good too. The reusability goal is rarely achieved by inheritance - usually
any serious changes to the derived class require edits in the base class
code too - but the code becomes less readable. For instance, in the trivial
ptr->method();
case - the source code for a method can be located in a) header file for
class A b) source file for class A c) header file for class B derived from A
d) source file for class B. This makes source reading much more complex.
IMHO C++-style declarative inheritance has very, very limited scope of
applicability - windowing UI classes is one of the few cases where
inheritance is good. This is one of the cases why the OO framework called
COM has no inheritance.
The classic C++ way of software desing is IMHO makes things easier - but a)
it makes things easier under limited conditions, not always b) it imposes
the performance burden and makes the code more bloated.

Surely, I agree that there are other possible ways of using C++ - and the
combination of C++ and the KISS principle can be very great.

Max


billy_dr...@my-deja.com

unread,
Jan 2, 2001, 3:12:25 AM1/2/01
to

> For instance, the usual C++ approach will have the consequence of
allocating
> huge number of tiny class instances - this leads sometimes to poor
> performance even in large user-mode apps (we wrote the OO database in
C++
> around the SQL server about 4 years ago. The performance was bad and
we were
> forced to use optimizations to avoid allocating all class instances by
> new(...). This optimization did not make the code more readable).
>

This is a big red flag indicating bad C++ class design. C++ is not
inherently slower than C, only bad design choices make it so. This has
been hashed and rehashed time and again, but give me any C driver, I
will write it in C++ and get the same or better performance period.

> Or, well, let's imagine things like STL's vectors and MFCs
CStringArray.
> Sorry, but I prefer RtlxxxGenericTable and InsertTailList to these
things.
> The reason is that C++ container classes impose heavy burden on the
> allocator - constant allocations/reallocations of the array body are
not so
> cheap.
> As about the kernel's primitives - the list node or the table entry
can
> usually be allocated as a part of the larger structure - thus
diminishing
> the burden on the allocator.
>

Once again I say you can't compare STL or MFC to something like WinDK,
where the vast majority of your allocations are done once at init. If
you are doing large numbers of allocations at anytime other than Init,
you are misusing C++, not WinDK's fault, not C++'s fault.

> >But, yes C++ classes do take a little more upfront
> > effort to learn, but saying that there is no gain from that effort
is
> > just plain idiocy. I don't believe that is opinion. You knocked
> > WinDK, what exactly was awful about the source you saw?
>
> The PnP and power IRP processing paths become just unreadable -
scattered
> between the framework's code and the driver's code - just for
instance.

Pnp and Power handlers are code you generally want to write once and
never again anyway, a perfect fit for C++. It does not alleviate your
need to learn WDM. Also, I find that code in WinDK quite easy to
follow, again I say it is a lack of understanding and practice with C++.

> Also:
> - in C, if I want to allocate structures from the lookaside, I just
call
> ExAllocateFromNPagedLookasideList.
> - in the classic C++ approach, I must declare the operator new() in
order to
> do this. Thus, the allocation logic becomes scattered over the class
> declaration and the caller code.
> Why not follow the KISS principle and keep all this logic in one
place?
>

Why could you not just call ExAllocateFromNPagedLookasideList in your
C++ driver, if you so prefered?? Besides how about something like a
state machine, I could do this easier and more error free in C++
anyday. You have to use the tool where it makes sense.

> Maybe this is my fault than when somebody says "C++", I recall the
> well-known approach of allocating huge number of different class
instances
> by new(...), which has its drawbacks. Yes, it is another layer of
> abstraction - but has its cost of heavy burden imposed on the
allocator.

What specifically is so bad about new? You have to allocate your
structures either way?? Yes C++ will possibly cost you more memory,
but if your allocations are done at Init, who cares? I would gladly
trade size for ease of use and reusability anyday. If size is
important, you probably aren't working on NT/2000/98 drivers. If you
are allocating all over the driver, your code is busted not C++.

> The "usual" C++ way is to use inheritance at all possible places -
not so
> good too. The reusability goal is rarely achieved by inheritance -
usually
> any serious changes to the derived class require edits in the base
class
> code too - but the code becomes less readable. For instance, in the
trivial
> ptr->method();
> case - the source code for a method can be located in a) header file
for
> class A b) source file for class A c) header file for class B derived
from A
> d) source file for class B. This makes source reading much more
complex.

Once again C++ will not protect you from bad class design, these are
arguments of bad implementation, not C++ limitations. Inheritance
should not be used everywhere possible, 'has a' should be used more
than 'is a' as a general rule, but many inexperienced C++ programmers
overuse the latter.

> IMHO C++-style declarative inheritance has very, very limited scope of
> applicability - windowing UI classes is one of the few cases where
> inheritance is good. This is one of the cases why the OO framework
called
> COM has no inheritance.

I don't disagree, inheritance is highly overrated, but is only one of
many C++ strengths over C. And in C++ at least you have the option of
using inheritance where it makes sense.

> The classic C++ way of software desing is IMHO makes things easier -
but a)
> it makes things easier under limited conditions, not always b) it
imposes
> the performance burden and makes the code more bloated.
>
> Surely, I agree that there are other possible ways of using C++ - and
the
> combination of C++ and the KISS principle can be very great.
>

Exactly, as C++ is a superset of C I don't know how C could ever be
argued as better. And, you have strong type checking, default
parameters, overloaded functions, pure virtual functions, etc. all of
which can be used in a manner to enforce more bullet proof code. The
strengths are many the weaknesses few.

Bill M.

Johan

unread,
Jan 2, 2001, 4:28:50 AM1/2/01
to
In article <0s605tst6mtlq16ks...@4ax.com>,
Mark Roddy <ma...@wattanuck.mv.com> wrote:

[snip]

>
> There aren't any pageable code or data sections in your driver unless
> you explicitly create one. End of story.
>

And a darn good one, too - even had a happy ending :-)

For following up on C++ in kernel mode - is it possible to tell the
compiler in which code segments to put the generated code for
parameterized classes?

Would you simply create an implementation file with a explicit
instantiation of the parameterized class and add the necessary pragmas
to that file?

// Johan

Maxim S. Shatskih

unread,
Jan 2, 2001, 7:23:38 AM1/2/01
to
> Pnp and Power handlers are code you generally want to write once and
> never again anyway, a perfect fit for C++. It does not alleviate your
> need to learn WDM.

This is a hype. One will need to learn WDM anyway - otherwise, he/she will
be uncapable of fixing different problems which will possibly arise.

>Also, I find that code in WinDK quite easy to
> follow, again I say it is a lack of understanding and practice with C++.

C code is always easier to follow. For instance, I cannot understand what is
the use of class wrappers around struct _MDL and struct _IRP. Any use of
them at all except overbloating the code?
Any advantages in:
pMdl->GetSystemAddress()
over
MmGetSystemAddressForMdl(Mdl)
The first one introduces some extra code which is completely unnecessary and
provides nothing useful.

> Why could you not just call ExAllocateFromNPagedLookasideList in your
> C++ driver, if you so prefered?? Besides how about something like a
> state machine, I could do this easier and more error free in C++
> anyday.

Recently implemented one in C. No problems at all (except overflowing the
kernel stack, which was easily fixed by calling KeInsertQueueDpc when the
recursion was too deep).

>You have to use the tool where it makes sense.

Agree. Nothing bad with C++ itself as a tool and as a language, but C++
usually assumes some coding practice, and this coding practice (MFC is an
example of it) is IMHO inacceptable in drivers.

> Once again C++ will not protect you from bad class design, these are
> arguments of bad implementation, not C++ limitations. Inheritance
> should not be used everywhere possible,

Agree. Looks like we are near to distinguish the C++ itself and some common
C++ coding practices.
For instance, some developers (who consider themselves very great :-) ) have
itching of making base classes. They are spending lots of time trying to
define the common part of 2 classes and to declare it as a base class.
This leads to:
1) features are moved from the derived class to the base one - the base
class becomes overbloated
2) what was previously a single source code module - now becomes 3 or more
source modules with the functionality scattered all over it

> Exactly, as C++ is a superset of C I don't know how C could ever be
> argued as better. And, you have strong type checking, default
> parameters, overloaded functions, pure virtual functions, etc. all of
> which can be used in a manner to enforce more bullet proof code. The
> strengths are many the weaknesses few.

There are some C++ features which are real black boxes. The template
expansion is one. Templates are nasty anyway - IMHO the only good use of
them is the "variable base class" as in ATL:
template<class T>
class CComObject : public T...
Templates are a good example of introducing obscurity which was absent in C.
Such black boxes are usually OK in the user mode app (after all, people
write apps in VB which is a single huge black box) - but not in drivers.

C enforces the KISS principle - while C++ does not, so many developer abuse
the C++ features.
The C library is usually much more intuitive and easier to use than the same
C++ one - compare stdio functions to iostream classes (why on Earth <<
operator means "write to stream"?)

BTW - note that practically all GNU open-source software is written in C,
not in C++.

Max


billy_dr...@my-deja.com

unread,
Jan 2, 2001, 11:55:20 AM1/2/01
to
It does not alleviate your
> > need to learn WDM.
>
> This is a hype. One will need to learn WDM anyway - otherwise, he/she
will
> be uncapable of fixing different problems which will possibly arise.

What did I just say in my last sentence there? You have to know WDM,
but once you do, why would you want to rewrite your Pnp and Power
handlers everytime? I can't think of a good reason.

> C code is always easier to follow.

This is definitely the opinion of a programmer that does not use C++
everyday. I used to feel the same way, but now I can follow C++ as
easily as C. And, I can use C++ much easier than C. Anyway, even if
it takes a little longer, which I don't think it does, who cares, the
benefits are worth it.

> For instance, I cannot understand what is
> the use of class wrappers around struct _MDL and struct _IRP. Any use
of
> them at all except overbloating the code?
> Any advantages in:
> pMdl->GetSystemAddress()
> over
> MmGetSystemAddressForMdl(Mdl)
> The first one introduces some extra code which is completely
unnecessary and
> provides nothing useful.
>

I don't see these examples in the WinDK drivers I look at, what is your
point? If you use a class to wrapper everything under the sun you have
made a mistake. Not a C++ problem, a bad programmer problem. I could
see using a class for IRP handling if the user so chose. That would be
perfectly reasonable, but if the user chose not to use the class, then
all they would have to do is not call 'new CIrp()' or whatever and
handle it themselves. Nothing forces the user to use the features,
that to me is one of the beauties of a toolkit like WinDK. I can use
the features I deem useful. And I get the added benefit of knowing the
code has been beaten to death by other users.

> Recently implemented one in C. No problems at all (except overflowing
the
> kernel stack, which was easily fixed by calling KeInsertQueueDpc when
the
> recursion was too deep).
>

I could easily do the same thing in C++ in exactly the same way as it
is a superset of C, but I could also have default parameters, strong
type checking, member variables, private or protected members etc., to
help make my code more robust :)

> Agree. Nothing bad with C++ itself as a tool and as a language, but
C++
> usually assumes some coding practice, and this coding practice (MFC
is an
> example of it) is IMHO inacceptable in drivers.

You assume MFC is somehow the default coding practice of C++. This may
be true for App programmers, but in no way resembles the tight lean
code I see in toolkits such as WinDK.

> Agree. Looks like we are near to distinguish the C++ itself and some
common
> C++ coding practices.
> For instance, some developers (who consider themselves very great :-
) ) have
> itching of making base classes. They are spending lots of time trying
to
> define the common part of 2 classes and to declare it as a base class.
> This leads to:
> 1) features are moved from the derived class to the base one - the
base
> class becomes overbloated
> 2) what was previously a single source code module - now becomes 3 or
more
> source modules with the functionality scattered all over it
>

This is not always a problem. It is only a problem if it affects
performance or legibility in some way, which the vast majority of the
code in a driver will not do. You have to keep in mind, that there are
usually only a couple of paths in your driver that have any real
consequence to performance. How fast you read the registry is usually
not an issue, for example. Legibility is somewhat in the eye of the
beholder, but I find C++ class following no better or worse than C
pointer tracking. The large majority of C++ code I have seen in kernel
space has been excellently written, is easy to follow and performs well.

> There are some C++ features which are real black boxes. The template
> expansion is one. Templates are nasty anyway - IMHO the only good use
of
> them is the "variable base class" as in ATL:
> template<class T>
> class CComObject : public T...
> Templates are a good example of introducing obscurity which was
absent in C.
> Such black boxes are usually OK in the user mode app (after all,
people
> write apps in VB which is a single huge black box) - but not in
drivers.
>

I could not disagree more. Template expansion is a difficult aspect of
C++ programming, but it is not a black box, it is most certainly
deterministic. I certainly would not rule out using templates where
they make sense. In fact there are certain features with templates you
could not get any other way. Again, it is a tool, again the misuse of
that tool is the fault of the programmer and has nothing whatsoever to
do with the language or its features, and again one must know the
proper place and time to use the tool.

> C enforces the KISS principle - while C++ does not, so many developer
abuse
> the C++ features.

C is assembly with descriptive function names and doesn't enforce much
at all. You can misuse a pointer in C much more easily than in well
written C++ code. C++ enforces good code which is why the errors of
bad code show up more in C++. It is more robust, which does put more
responsibility on the programmer, which could be arguably a bad thing,
but I haven't heard that argument here. C++ is in itself a much better
language than C. It is more robust, capable, and loses nothing over
C. If you are worried about misuse, then maybe we should all write our
drivers in Java, that way nobody could get a pointer wrong, and
deletions would be handled automagically. As it is, I think kernel
programming requires a certain skill level, and if the programmer
doesn't have it, C is going to be every bit as dangerous in said
programmer's hands as C++.

> The C library is usually much more intuitive and easier to use than
the same
> C++ one - compare stdio functions to iostream classes (why on Earth <<
> operator means "write to stream"?)

Opinion. I think C++ stdio functions are much more intuitive to use.
But they don't exist in kernel mode anyway, so the argument here is
moot. There is nothing intuitive about printf or KdPrint either.

>
> BTW - note that practically all GNU open-source software is written
in C,
> not in C++.
>

I rest my case. This is the single best argument I have ever seen for
C++. I have looked at some of that open-source crap, and I must say,
you do get what you pay for. I love single letter descriptive variable
names like 'a', they are so meaningful. If GNU is your idea of good
coding practice, then stay with C. No offense really, but the Linux
code I have seen is really really bad and hard to follow. I love the
coding standard of the day effect too. Working != good.

Felix Kasza [MVP]

unread,
Jan 2, 2001, 2:03:10 PM1/2/01
to
Mark,

> Now you appear to be saying that in fact you have
> no clue if there is a problem or what section vtables
> are in.

Actually, I do have some clues, but they are all wrt a specific compiler
version -- and I intend to verify my results when the next compiler
release arrives.

But, just to demonstrate that things are not always as clear-cut as they
may seem:

// foobar.h
class Foo
{
Foo(); // implementation elsewhere
~Foo(); // --"--
// ... more ...
};

class Bar: public Foo
{
Foo fooinstance;
// ... more ...
};

// mydriver.cpp
#include "foobar.h"

#pragma code_seg( "INIT" )

NTSTATUS MyInitFunc()
{
Bar barinstance;

// ...
}

#pragma code_seg() // back to .text

void OtherFunc()
{
Bar anotherbar;

// ...
// BOOM!
}

When barinstance in MyInitFunc goes out of scope, the compiler
recognises that it must generate a default dtor for Bar, so that it can
(from there) invoke the dtors for base classes and embedded objects.
Unfortunately, the dtor will be emitted to the INIT section; when
OtherFunc() later is called, the call to the default dtor for anotherbar
will use the default destructor generated into the INIT section. Boom.

Similar issues hold for the vector delete destructor.

Oh, and vtables may well be in INIT if one makes the mistake of defining
the class there. It has happened to me, and others may not be immune to
making mistakes, either.

Slava M. Usov

unread,
Jan 2, 2001, 4:37:37 PM1/2/01
to

<billy_dr...@my-deja.com> wrote in message
news:92t15j$4qr$1...@nnrp1.deja.com...

[...]

> You assume MFC is somehow the default coding practice of C++. This may
> be true for App programmers, but in no way resembles the tight lean
> code I see in toolkits such as WinDK.

I would even say that MFC is one simple example of bad C++. MFC is nothing
but deep inheritance chains that many people considered the only 'true'
C++'ism a few years ago. And it is true that deep inheritance makes things
obscure and is really a misfeature. What is the point of deriving CWindow
and CApp from the very same CObject?

Whatever, C++ today is vastly more than just inheritance. My favorite
feature is declaration-and-initialization where needed, not one thousand
lines in advance. That and const provide for robust and efficient code. Of
course, this goes particularly well together with complex objects: now I can
define and initialize one just where I need it, and never mind dynamic
allocation; contrast that with the typical C way of doing the same: declare
a pointer at the beginning of the function, then, thousand lines below,
malloc()/ExAllocatePool() some memory, do some magic initialization, then
*remember* to free() it. Destructors are another great feature, now I can
just specify what needs to be done to delete an object and forget about it;
with C, I must be very careful *not* to forget!

OK, I did say that deep inheritance was bad, but sane virtual functions, in
particular as means of declaring an interface, do we need to debate their
tremendous utility?

Only these features, and I take C++ over C anyday. But don't give me any
MFC, please.

Slava


Carl Mette

unread,
Jan 2, 2001, 7:00:47 PM1/2/01
to
Thanks Gary your guidance is appreciated!
I tried using your described approach to C++ exception Handling and I'm getting the following warnings:

cpprt.lib(exsup.obj) : warning LNK4006: __global_unwind2 already defined in
ntoskrnl.lib(exsup.obj); second definition ignored
cpprt.lib(exsup.obj) : warning LNK4006: __local_unwind2 already defined in ntoskrnl.lib(exsup.obj);
second definition ignored
cpprt.lib(exsup.obj) : warning LNK4006: __abnormal_termination already defined in
ntoskrnl.lib(exsup.obj); second definition ignored
.\i386\checked\VniDba.sys : warning LNK4088: image being generated due to /FORCE option; image may
not run
Did you encounter any of these problems with your build? Do I need to do anything about them or are
they harmless?
If I remove exsup.obj from the list of objects in the cpprt.lib, then lowhelpr.obj has the following
errors:
__NLG_Notify error: unresolved external
__NLG_Notify1 error: unresolved external
__NLG_Destination error: unresolved external
Regards,
Carl


Gary Nebbett wrote:

> http://www.deja.com/getdoc.xp?AN=648586436&fmt=text describes an approach to C++ exception handling
> in kernel mode.
>
> Gary

Gary Nebbett

unread,
Jan 3, 2001, 4:49:14 AM1/3/01
to
"Carl Mette" <cme...@vertical.NO_SPAM.com> wrote in message
news:3A526BAF...@vertical.NO_SPAM.com...

> I tried using your described approach to C++ exception Handling and I'm getting the following
warnings:
[...]

Hello Carl,

It builds cleanly for me (Visual C++ version 6 and Windows 2000 DDK).

If you can send me any commands or source files that you are using (and that were not in the
original article, e.g. the compiler command line used to build cpprt.obj), then I will see if I can
track down the problem.

Gary

Mark Roddy

unread,
Jan 3, 2001, 6:03:48 PM1/3/01
to
On Tue, 02 Jan 2001 19:03:10 +0000, "Felix Kasza [MVP]"
<fel...@mvps.org> wrote:


>Actually, I do have some clues, but they are all wrt a specific compiler
>version -- and I intend to verify my results when the next compiler
>release arrives.


You really did have specific concerns. I stand by my earlier
statement: by default all kernel code and data is non-pageable. Unless
you create a pageable data segment your vtables cannot be anywhere
except nonpaged pool.

I'll amend it to "pageable or discardable".

I'll go further: unless you know exactly what you are doing, you
should never attempt to use the compiler pragma's to adjust the
linkage sections for your driver code and data. This includes, as far
as I am concerned, making your driver entry routine discardable. For
W2K drivers however, making driver entry discardable is trivial as
driver entry no longer really does much of anything anyhow. It is, for
the same reason, basically a waste of effort.

I have no doubt that if one goes about issuing #pragma code_seg's or
#pragma data_seg's all over one's driver that BAD THINGS CAN HAPPEN.
This is, once again, not a C++ vs. C issue. Certainly as well, C++
makes understanding EXACTLY what a #pragma code_seg might do more
difficult, due to the presence of compiler emitted code and data. I
have a simple solution: don't do that. The default behavior of the
compiler and linker is C++ safe.

There actually is a KB article about the dangers of using code_seg
with respect to C++ generated code and data, but the KB article
insists that it is a programming error to not follow every
code_seg("blortz") with a code_seg() to return the linker to its
default behavior. I persist in my belief that if you are going to
modify the linker behavior: YOU REALLY SHOULD KNOW WHAT YOU ARE DOING.
I hate the fact that the ddk samples are littered with pageable this
and discardable that.

By the way, the W2K DDK samples contain several C++ coded driver
samples. The theory that this is somehow 'not supported' would appear
to be obsolete.

Finally your example has nothing to do with vtables and everything to
do with bad C++ code. I personally would be happy if the compiler had
a switch that flagged its desire to emit a default constructor or
destructor as an error. Not providing a destructor for a derived class
is a basic code blunder for a lot of reasons, your example being a
fine case in point.

0 new messages